使用fork()的奇怪行为;

时间:2017-03-03 00:20:10

标签: c fork

我在C

中有这个小程序
main(int argc, char **argv)
{
    forkit(4);
}
void forkit(int n)
{
if(n > 0)
    {
        fork();
        printf("%d \n", n);
        forkit(n-1);
    }
}

打印

4 4 3 3 3 3 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

30个数字,全部用新行。但是,如果我删除\n语句中的printf,则会打印出来:

4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1 4 3 2 1

如果没有新行,它会提供64个数字。

如此小的变化如何产生如此不同的结果?

1 个答案:

答案 0 :(得分:5)

非常好的问题,一些微妙的事情。

正在发生的事情是printf的输出是行缓冲并在换行时刷新。

所有这一切,不会影响大多数程序的输出,只会影响速度。

但是当你分叉时,两个孩子中现在都存在尚未输出的缓冲I / O.使用 in 中的换行符已经发生输出,因此它不再在孩子中待定。

这就是解释。如果不清楚,另一种表达方式是:没有换行符,挂起的输出乘以进程树中未来子节点的数量。使用换行符,它只是过去发生的输出,程序的工作方式与您期望的一样。

请注意,即使没有换行符,输出最终也会被刷新,但是当程序调用{​​{1}}时会发生这种情况。到那时,它已经分叉并传递了它的挂起(即缓冲 )输出。

顺便说一句,如果你将输出重定向到一个文件,它将是块缓冲,你可能会在两种情况下都看到类似的结果(除了换行符)。