考虑下面的代码:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
int i;
for(i = 0; i < 2; i++)
{
fork();
printf(".");
}
return 0;
}
此程序输出8个点。 这怎么可能? 不应该有6点呢?
考虑下面的代码:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
int i;
for(i = 0; i < 2; i++)
{
fork();
printf(".");
}
return 0;
}
此程序输出8个点。 这怎么可能? 不应该有6点呢?
所述fork()
基元通常延伸的想象力。 直到你得到它的感觉,你应该追查在纸上每一个操作是什么,以及账户的进程数。 不要忘了,fork()的创建当前进程的一个近乎完美的副本。 最显著的差异(在大多数情况下)是fork()
的返回值父母和孩子之间的区别。 (由于该代码忽略返回值,它没有什么区别。)
因此,在第一次,有一个过程。 这将创建一个第二过程,这两者的打印点和循环。 在他们的第二次迭代,每个创建另一个副本,所以有四个处理打印一个点,然后退出。 因此,我们可以很容易地占据六个点,像你期望的那样。
然而,什么样printf()
确实是缓冲输出。 所以写的时候,从当时只有两个进程的第一个点不会出现。 这些点保留在缓冲器-其在叉()复制。 它不是直到进程即将退出时出现的缓冲点。 四个过程打印缓冲点,再加上新给出8点。
如果你想避免这种行为,调用fflush(stdout);
后printf()
你必须在输出流未提交的缓冲区 。 stdout是行缓冲,并且缓冲器与所述过程的其余部分一起复制。 当程序终止时,未提交的缓冲器(一次为每个处理)写入两次。 无论使用
printf("a\n");
和
printf("a "); fflush(stdout);
不会出现问题。
在你的第一个例子,您创建各有两个点在其输出流缓冲四个过程。 当每个流终止时,它刷新它的缓冲液,生成8个点。
当i = 0
Process_1:缓冲文本= 1点
Process_2(由Process_1创建):缓冲文本= 1点
i = 1时
Process_3(由Process_1创建):由本身继承Process_1并打印1个点1个缓冲点。 在总Process_3打印2个点。
Process_4(由Process_2创建):由本身继承Process_2并打印1个点1个缓冲点。 在总Process_4打印2个点。
Process_1:打印2个点(一个缓冲点i = 0时,另一个点i = 1时)
Process_2:打印2个点(一个缓冲点i = 0时,另一个点i = 1时)
最终输出:8点。 :)