扫码关注官方订阅号
然后结果为:
==================================不太理解为何父进程已经把文件关了,而子进程依旧可以写入。 而且fork()创建的子进程不是应该执行fork之后的代码吗,为何题2又可以把第一句话写入
业精于勤,荒于嬉;行成于思,毁于随。
首先要理解fork的一个特性: 父进程的所有打开文件描述符都会被复制到子进程中,父、子进程的每个相同的打开描述符共享一个文件表项。如下图(摘自APUE)所示。另外,在文件表中还有一项:打开文件引用计数,引用这个文件对象的描述符数(dup和fork都会增加这个计数,第一次open会使此计数为1,close会减小此计数,为0时销毁文件对象)。所以在程序的运行过程中,不管是父进程还是子进程先close(fd)或fclose(fp),该文件表依然存在并没有被销毁,只有当文件表中的打开文件引用计数为0时才会销毁这个文件表对象。
fork
dup
open
close
close(fd)
fclose(fp)
题1中的I/O都是通过Linux系统调用来完成的,这些函数也常被称为不带缓冲的I/O(unbuffered I/O)。所以每一次调用都会立即写入文件中。而对于题2中的标准I/O库函数来说,都是带缓冲的,文件一般都是全缓冲,也就是说一定要把缓冲区填满才能进行实际的I/O操作。在执行语句fprintf(fp, "%s", msg1);时,由于没有填满缓冲区而实际的I/O操作并未完成。这时却调用了fork函数,这个函数同时也会把该缓冲区复制一份给子进程,这样在父、子进程中就各有一份msg1,当缓冲区填满后就会被刷新以进行实际的I/O操作(写入文件)。int fflush ( FILE * stream );函数能够提供手动进行刷新缓冲区,楼主可以试试在将msg1写入文件这条语句后面加上fflush(fp);则得出的结果将会和题1一样。
fprintf(fp, "%s", msg1);
msg1
int fflush ( FILE * stream );
fflush(fp);
个人认为fork出来的东西是拷贝的,意思就是
表打我。。。
子进程会复制一父进程的变量以及环境, fork()之后执行fork()下面的代码, 请看UNIX环境编程·进程篇
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
扫描下载App
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
首先要理解
fork
的一个特性: 父进程的所有打开文件描述符都会被复制到子进程中,父、子进程的每个相同的打开描述符共享一个文件表项。如下图(摘自APUE)所示。另外,在文件表中还有一项:打开文件引用计数,引用这个文件对象的描述符数(dup
和fork
都会增加这个计数,第一次open
会使此计数为1,close
会减小此计数,为0时销毁文件对象)。所以在程序的运行过程中,不管是父进程还是子进程先close(fd)
或fclose(fp)
,该文件表依然存在并没有被销毁,只有当文件表中的打开文件引用计数为0时才会销毁这个文件表对象。题1中的I/O都是通过Linux系统调用来完成的,这些函数也常被称为不带缓冲的I/O(unbuffered I/O)。所以每一次调用都会立即写入文件中。而对于题2中的标准I/O库函数来说,都是带缓冲的,文件一般都是全缓冲,也就是说一定要把缓冲区填满才能进行实际的I/O操作。在执行语句
fprintf(fp, "%s", msg1);
时,由于没有填满缓冲区而实际的I/O操作并未完成。这时却调用了fork
函数,这个函数同时也会把该缓冲区复制一份给子进程,这样在父、子进程中就各有一份msg1
,当缓冲区填满后就会被刷新以进行实际的I/O操作(写入文件)。int fflush ( FILE * stream );
函数能够提供手动进行刷新缓冲区,楼主可以试试在将msg1
写入文件这条语句后面加上fflush(fp);
则得出的结果将会和题1一样。个人认为fork出来的东西是拷贝的,意思就是
表打我。。。
子进程会复制一父进程的变量以及环境,
fork()之后执行fork()下面的代码,
请看UNIX环境编程·进程篇