简体   繁体   English

使用fork()的奇怪行为;

[英]Weird behaviour using fork();

I have this tiny program in C 我在C中有这个小程序

main(int argc, char **argv)
{
    forkit(4);
}
void forkit(int n)
{
if(n > 0)
    {
        fork();
        printf("%d \n", n);
        forkit(n-1);
    }
}

which prints 打印

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 numbers, all in new lines. 所有新行都有30个数字。 However, if I remove the \\n in the printf statement it prints this: 但是,如果我删除printf语句中的\\n ,则打印出:

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

Without new line it gives 64 numbers. 没有新行,它会提供64个数字。

How is such a small change giving such different results? 如此微小的变化如何产生如此不同的结果?

Very good question, there is something subtle going on. 这个问题非常好, 事情一些微妙。

What's happening is that printf's output is line buffered and flushed at newlines. 发生的事情是printf的输出是行缓冲并在换行时刷新。

All by itself, that doesn't affect the output of most programs, just the speed. 一直以来,这不会影响大多数程序的输出,只影响速度。

But when you fork, buffered I/O that hasn't yet been output is now present in both children. 但是当你分叉时,两个孩子中现在都存在尚未输出的缓冲I / O. With the newline in that output has already happened so it is no longer pending in the child. 随着该输出换行已经发生,因此在孩子不再悬而未决。

That's the explanation. 这就是解释。 If it isn't clear, another way to phrase it is: without the newline, the pending output is multiplied by the number of future children in the process tree. 如果不清楚,另一种表达方式是:没有换行符,挂起的输出乘以进程树中未来子节点的数量。 With the newline, it's just output that happened in the past and the program works like you expect it to. 使用换行符,它只是过去发生的输出,程序就像你期望的那样工作。

Note that the output eventually gets flushed even without the newline, but it happens when the program calls exit(3). 请注意,即使没有换行,输出最终也会被刷新,但是当程序调用exit(3).时会发生这种情况exit(3). By then, it has already forked and passed on it's pending (ie, buffered ) output. 到那时,它已经分叉并传递了它的挂起(即缓冲 )输出。

By the way, if you redirect the output to a file, it will be block buffered and you will probably see similar results (except for the newlines) in both cases. 顺便说一下,如果将输出重定向到文件,它将被块缓冲 ,在这两种情况下你可能会看到类似的结果(除了换行符)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM