//////////////1,文件描述子
int main()
{
int fd;
int pid;
char msg1[] = "hello\n";
char msg2[] = "world\n";
if ((fd=creat("a.txt",0644)) == -1)
return -1;
if (write(fd,msg1,strlen(msg1)) == -1)
return -1;
if ((pid = fork()) == -1)
return -1;
if (write(fd,msg2,strlen(msg2)) == -1)
return -1;
close(fd);
return 0;
}
///////////////2文件结构指针
int main()
{
FILE *fp;
int pid;
char msg1[] = "hello\n";
char msg2[] = "world\n";
if ((fp = fopen("a.txt","w")) == NULL)
return -1;
fprintf(fp,"%s",msg1);
if ((pid = fork()) == -1)
return -1;
fprintf(fp,"%s",msg2);
fclose(fp);
return 0;
}
6 个解决方案
#1
文件指针是标准库定义的,文件描述符是*nix系统里专有的吧
#2
好像不是很清楚啊,有谁能解释一下上面这两个程序的结果为什么是怎样么??
#3
这是因为库IO做了缓存,在fork之前没有正在输出,所以fork时该缓存被复制。你在第二个程序的:
int ((pid = fork()) == -1)前边加上fflush(fp)就可以看出来了。
int ((pid = fork()) == -1)前边加上fflush(fp)就可以看出来了。
#4
这个显然么……
fork的时候连带fd一起复制了,而C的标准IO对于文件默认是全缓冲。即除非手动刷新(譬如fseek、fflush等),否则要等缓冲区全满才会调用write来写文件。而在刷新缓冲区之前你fork了,所以造成了缓冲区也被同时复制,所以是两个进程都往文件里面写同样的内容。而且两个内容不会发生重叠,这个是因为内核里面共享了打开的文件,使用的是同一个偏移量。
fork的时候连带fd一起复制了,而C的标准IO对于文件默认是全缓冲。即除非手动刷新(譬如fseek、fflush等),否则要等缓冲区全满才会调用write来写文件。而在刷新缓冲区之前你fork了,所以造成了缓冲区也被同时复制,所以是两个进程都往文件里面写同样的内容。而且两个内容不会发生重叠,这个是因为内核里面共享了打开的文件,使用的是同一个偏移量。
#5
w r i t e函数是不带缓存的。
因为在f o r k之前调用w r i t e,所以其数据写到标准输出一次。但是,标准I / O库是带缓存的。回
注意:并不是标准I/O就默认是全缓冲,如果标准输出连到终端设备(比如你的屏幕),则它是行缓存的,否则它是全缓存的。
通俗点:
行缓冲,一行完了再输出。
全缓冲,全部完了再输出。
因为在f o r k之前调用w r i t e,所以其数据写到标准输出一次。但是,标准I / O库是带缓存的。回
注意:并不是标准I/O就默认是全缓冲,如果标准输出连到终端设备(比如你的屏幕),则它是行缓存的,否则它是全缓存的。
通俗点:
行缓冲,一行完了再输出。
全缓冲,全部完了再输出。
#6
对不起,我上面的直接复制的书上内容,忘了改了。更改为:
w r i t e函数是不带缓存的。
因为在f o r k之前调用w r i t e,所以其数据写到对应描述符。但是,标准I / O库是带缓存的。
注意:并不是标准I/O就默认是全缓冲,如果标准输出连到终端设备(比如你的屏幕),则它是行缓存的,否则它是全缓存的。
通俗点:
行缓冲,一行完了再输出。
全缓冲,全部完了再输出。
w r i t e函数是不带缓存的。
因为在f o r k之前调用w r i t e,所以其数据写到对应描述符。但是,标准I / O库是带缓存的。
注意:并不是标准I/O就默认是全缓冲,如果标准输出连到终端设备(比如你的屏幕),则它是行缓存的,否则它是全缓存的。
通俗点:
行缓冲,一行完了再输出。
全缓冲,全部完了再输出。
#1
文件指针是标准库定义的,文件描述符是*nix系统里专有的吧
#2
好像不是很清楚啊,有谁能解释一下上面这两个程序的结果为什么是怎样么??
#3
这是因为库IO做了缓存,在fork之前没有正在输出,所以fork时该缓存被复制。你在第二个程序的:
int ((pid = fork()) == -1)前边加上fflush(fp)就可以看出来了。
int ((pid = fork()) == -1)前边加上fflush(fp)就可以看出来了。
#4
这个显然么……
fork的时候连带fd一起复制了,而C的标准IO对于文件默认是全缓冲。即除非手动刷新(譬如fseek、fflush等),否则要等缓冲区全满才会调用write来写文件。而在刷新缓冲区之前你fork了,所以造成了缓冲区也被同时复制,所以是两个进程都往文件里面写同样的内容。而且两个内容不会发生重叠,这个是因为内核里面共享了打开的文件,使用的是同一个偏移量。
fork的时候连带fd一起复制了,而C的标准IO对于文件默认是全缓冲。即除非手动刷新(譬如fseek、fflush等),否则要等缓冲区全满才会调用write来写文件。而在刷新缓冲区之前你fork了,所以造成了缓冲区也被同时复制,所以是两个进程都往文件里面写同样的内容。而且两个内容不会发生重叠,这个是因为内核里面共享了打开的文件,使用的是同一个偏移量。
#5
w r i t e函数是不带缓存的。
因为在f o r k之前调用w r i t e,所以其数据写到标准输出一次。但是,标准I / O库是带缓存的。回
注意:并不是标准I/O就默认是全缓冲,如果标准输出连到终端设备(比如你的屏幕),则它是行缓存的,否则它是全缓存的。
通俗点:
行缓冲,一行完了再输出。
全缓冲,全部完了再输出。
因为在f o r k之前调用w r i t e,所以其数据写到标准输出一次。但是,标准I / O库是带缓存的。回
注意:并不是标准I/O就默认是全缓冲,如果标准输出连到终端设备(比如你的屏幕),则它是行缓存的,否则它是全缓存的。
通俗点:
行缓冲,一行完了再输出。
全缓冲,全部完了再输出。
#6
对不起,我上面的直接复制的书上内容,忘了改了。更改为:
w r i t e函数是不带缓存的。
因为在f o r k之前调用w r i t e,所以其数据写到对应描述符。但是,标准I / O库是带缓存的。
注意:并不是标准I/O就默认是全缓冲,如果标准输出连到终端设备(比如你的屏幕),则它是行缓存的,否则它是全缓存的。
通俗点:
行缓冲,一行完了再输出。
全缓冲,全部完了再输出。
w r i t e函数是不带缓存的。
因为在f o r k之前调用w r i t e,所以其数据写到对应描述符。但是,标准I / O库是带缓存的。
注意:并不是标准I/O就默认是全缓冲,如果标准输出连到终端设备(比如你的屏幕),则它是行缓存的,否则它是全缓存的。
通俗点:
行缓冲,一行完了再输出。
全缓冲,全部完了再输出。