当前位置: 技术问答>linux和unix
关于fork,系统调用,库函数的问题
来源: 互联网 发布时间:2017-02-23
本文导语: 一段很简单的输入字符到文件的代码,先是使用系统调用: #include #include #include int main() { int fd; int pid; char msg1[]="Test 1 2 3 ..n"; char msg2[]="Hello, hellon"; if...
一段很简单的输入字符到文件的代码,先是使用系统调用:
执行后结果:
再使用c的库函数重写该程序:
执行后结果是:
为什么使用库函数的时候父进程会打印三次,我完全不能理解。
#include
#include
#include
int main()
{
int fd;
int pid;
char msg1[]="Test 1 2 3 ..n";
char msg2[]="Hello, hellon";
if((fd=creat("testfile",0644))==-1)
return 0;
if(write(fd,msg1,strlen(msg1))==-1)
return 0;
if((pid=fork())==-1)
return 0;
if(write(fd,msg2,strlen(msg2))==-1)
return 0;
close(fd);
return 1;
}
执行后结果:
Test 1 2 3 ..
Hello, hello
Hello, hello
再使用c的库函数重写该程序:
#include
#include
int main()
{
FILE *fp;
int pid;
char msg1[]="Test 1 2 3 ...";
char msg2[]="Hello, hello";
if((fp=fopen("testfile2","w"))==NULL)
return 0;
fprintf(fp,"%s pid:%dn",msg1,getpid());
if((pid=fork())==-1)
return 0;
fprintf(fp,"%s pid:%dn",msg2,getpid());
fclose(fp);
return 1;
}
执行后结果是:
Test 1 2 3 ... pid:8795
Hello, hello pid:8795
Test 1 2 3 ... pid:8795
Hello, hello pid:8796
为什么使用库函数的时候父进程会打印三次,我完全不能理解。
|
因为FILE对于文件使用 _IOFBF 全缓冲, n是不会冲刷buffer的。
所以fork后,子进程的fp->buffer里的内容就是父进程写出的但还留在buffer里的内容,子进程继续fprintf就是追加到buffer,最后父子进程分别关闭,各自冲刷各自的2行数据,一共4行。
所以fork后,子进程的fp->buffer里的内容就是父进程写出的但还留在buffer里的内容,子进程继续fprintf就是追加到buffer,最后父子进程分别关闭,各自冲刷各自的2行数据,一共4行。
|
fprintf只是写到磁盘缓冲里,并没有写磁盘文件.
在fprintf后面加一句fflush(fp);(fp是你的文件指针)就可以了
fprintf的确每fork一个进程才写一次,因为必须写满缓冲后再批量写磁盘的原因,你会感觉文件是批量生成的.
在fprintf后面加一句fflush(fp);(fp是你的文件指针)就可以了
fprintf的确每fork一个进程才写一次,因为必须写满缓冲后再批量写磁盘的原因,你会感觉文件是批量生成的.
|
#include
#include
int main()
{
FILE *fp;
int pid;
char msg1[]="Test 1 2 3 ...";
char msg2[]="Hello, hello";
if((fp=fopen("testfile2","w"))==NULL)
return 0;
fprintf(fp,"%s pid:%dn",msg1,getpid());
fflush(fp); //这样就好了
if((pid=fork())==-1)
return 0;
fprintf(fp,"%s pid:%dn",msg2,getpid());
fclose(fp);
return 1;
}
|
说的再细一点吧:
fprintf只是写到磁盘缓冲里,fork之后,连带这个磁盘缓冲也一起复制了,而且还不输出,直到fclose(fp)了,才强制刷新磁盘缓冲区,写进磁盘文件。
可以,在fclose(fp)前加个sleep(20);然后在这20秒内看testfile2,不会发现什么也没有,20秒后就一次性全都写进去了。
fprintf只是写到磁盘缓冲里,fork之后,连带这个磁盘缓冲也一起复制了,而且还不输出,直到fclose(fp)了,才强制刷新磁盘缓冲区,写进磁盘文件。
可以,在fclose(fp)前加个sleep(20);然后在这20秒内看testfile2,不会发现什么也没有,20秒后就一次性全都写进去了。