Fork()操作系统。输出4个“hi”,预期输出3个“hi”。

4
for(i=0;i<2;i++)
      if(fork()==0)
          printf("Hi");

我预期得到3个“Hi”,但实际上得到了4个。 因此,我将printf编辑为printf("Hi %d %d %d ",i,getpid(),getppid());。 所创建的第一个子进程打印出两个相同的“Hi”,其值都为0,而且它的pid和父进程的pid也相同。为什么?


哪个操作系统?我在OS X下有3个。 - Vadim Key
我使用Ubuntu。您也可以尝试在线终端。 - Abhishek
1个回答

1

这很有趣,看起来答案是输出缓冲。例如我们有:

#include <unistd.h>
#include <stdio.h>

int main() {
  for(int i=0;i<2;i++) {
    if(fork()==0) {
      printf("Hi %d %d %d\n",i,getpid(),getppid());
    }
  }
}

如果在终端中运行此代码,将会有3行输出,但如果将输出重定向到less,则会有4行输出!

如果在printf()之后刷新缓冲区,问题将会消失:

  // ...
  printf("Hi %d %d %d\n",i,getpid(),getppid());
  fflush(stdout);
  // ...

这是因为stdout被缓冲,所以当进程分叉时,缓冲区仍未刷新。
从man stdout中可以得知:
stderr流是不带缓冲的。当stdout指向终端时,它是行缓冲的。直到调用fflush(3)或exit(3),或者打印换行符之前,部分行不会出现。这可能会产生意外的结果,特别是在调试输出方面。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接