当父进程和subprocess读取相同的文件并写入其他同一文件时会发生什么?

#include <fcntl.h> #include <stdlib.h> int fdrd,fdwt; char c; void rdwrt(); main(int argc,char *argv[]) { if(argc!=3) exit(1); if((fdrd=open(argv[1],O_RDONLY))==-1) exit(1); if((fdwt=creat(argv[2],0666))==01) exit(1); fork(); rdwrt(); exit(0); } void rdwrt() { for(;;) { if(read(fdrd,&c,1)!=1) return; write(fdwt,&c,1); } } 

该程序分叉一个subprocess,然后父进程和subprocess尝试读取相同的input文件并写入相同的输出文件。

像这样执行这个程序:

 [root@localhost]./a.out input output 

input文件的内容是:

 abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz 

我认为输出文件对input文件应该有相同数量的字符,尽pipe根据这两个进程的竞争,字符顺序可能不一样。

事实certificate,输出文件是:

 abcdefghijklmnonqbcdefghijklwxyczdefjklpqrstuvwxyz abcefgklmvwxefgklmnopqrstuvw qrstuyz abcdhijxyz 

实际上,这两个文件有不同的字符编号

 [root@localhost]wc -m input output 162 input 98 output 

现在我想知道为什么?

输出文件的内容将很难预测,因为你的程序包含竞争条件 。 具体来说,这取决于进程调度。

请求更新:

这个问题实际上比乍一看更有趣。

我要做一些预测(测试成功…)

在类Unix系统上1是的 ,字符的数量总是相同的,但是顺序很难预测。

你标记了你的问题linux unix ,并且在那些系统中,所有这些都正确地实现了fork模型,两个孩子将共享fdrd两个(分叉)实例的单个文件位置,并且它们将共享这两个实例的第二个文件位置的fdwr

如果你可以放慢时间观看程序运行,那么在任何时候都有你知道的东西和你不知道的东西。

你不知道哪个孩子会赢得比赛来完成下一次阅读,但是你知道胜利者将会阅读哪个角色,因为他们总是处于相同的文件位置。 获胜者获得下一个角色后,你仍然不知道谁会读下一个角色,因为比赛还在继续。

事实上,同样的过程有可能再次赢得比赛,再次,因为调度程序可能不会想要在非常短的时间内运行它。

在任何时候,你也知道下一个字符将被写入EOF,因为再次共享写入位置。

现在,你可能会问,如果两个进程总是在同一个输入和输出文件位置,那么文件如何被破解?

那么,有不止一个种族,一个读,一个写。 (或者一个,有点复杂的比赛)。一个孩子可能已经读了它的性格,但是当它得到时间切片时,却没有写出来。 所以现在它开始失去了写入声明的竞赛,然后可能进行几次读/写的迭代。 所以一个角色可以挂在一个小孩身上。

最后,在运行于其他操作系统的仅仅API兼容的C环境中,任何事情都可能发生。 OP的系统似乎是其中之一,或者测试是有缺陷的。 我的OSX系统的行为如预期。


1.“真正的”UNIX,* BSD,OSX或Linux。