Fork ()分支比预期的多?

考虑下面这段代码:

#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个点代替?

7785 次浏览

fork()原语常常能拓展想象力。直到你对它有了一定的感觉,你应该在纸上描绘出每个操作是什么,并说明进程的数量。不要忘记 fork ()创建了当前进程的一个近乎完美的副本。最显著的差异(在大多数情况下)是 fork()的返回值在父级和子级之间是不同的。(因为这段代码忽略了返回值,所以没有区别。)

所以,首先,有一个过程。这将创建第二个进程,这两个进程都打印一个点和一个循环。在第二次迭代中,每个进程创建另一个副本,因此有四个进程打印一个点,然后退出。所以我们可以很容易地解释六个点,就像你期望的那样。

然而,printf()真正做的是缓冲它的输出。所以当只有两个进程时,第一个点在写入时不会出现。这些点保留在 buffer & mash; 中,它在 fork ()处被复制。直到进程即将退出时,才会出现缓冲点。四个过程打印一个缓冲点,加上新的一个给8点。

如果您想避免这种行为,请在 printf()之后调用 fflush(stdout);

你有 输出流中的未提交缓冲区。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个点。过程 _ 3总共打印2个点。

Process _ 4(由 Process _ 2创建) : 从 Process _ 2继承1个带缓冲的点,并自行打印1个点。过程 _ 4总共打印2个点。

Process _ 1: 打印2个点(i = 0时打印一个缓冲点,i = 1时打印另一个点)

Process _ 2: 打印2个点(i = 0时打印一个缓冲点,i = 1时打印另一个点)

最终输出: 8点:)