在一个POSIX系统,通过一个fork
调用由子进程继承文件描述符指向同一个文件描述符在全系统表。下面是从Linux手册页相关的报价为开放式(2):
术语打开文件的描述是使用POSIX指 在打开文件的全系统表中的项目之一... 当文件描述符被复制(用DUP(2)或类似的),则 重复是指相同的开放文件描述作为原始 文件描述符,并且两个文件描述符因此共享 文件偏移量和文件状态标志。这种共享也可以进程之间发生 :经由叉(2)创建继承父的文件描述符 重复子进程,和这些重复 指代相同的打开的文件的描述。
这意味着,父母和孩子分享文件偏移量相同的信息,并在一个读将改变所有其它进程的偏移看到。如果在读取之间没有并行读取进程,则不会有两个进程读取相同的数据。
您可以在下面的测试程序,它打印在命令行给出的文件的前20个字符在行动看到这一点。 (如果位置信息不共享,则会打印前10个字符两次)。
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
char buffer[256];
int
main(int argc, char ** argv)
{
int fd = open(argv[1], O_RDONLY);
fork();
read(fd, buffer, 10);
write(1, buffer, 10);
return 0;
}
无论其,这是一个巨大的“但是”,这仅适用于低级别的系统调用接口读取文件:open(2)
,read(2)
等,如果你正在使用缓冲更高级别界面,如fgets
和其他功能stdio.h
,事情变得复杂。当进程分叉,即使他们继承指向单一的全系统,共享的内核文件信息结构文件描述符的副本,他们也会沿用使用stdio.h
电话用户空间的缓存信息独立份,并且这个缓冲信息包括它自己的偏移(显然是缓冲区),它们在进程之间不同步。