【问题标题】:What happens if I call fork() inside main? [duplicate]如果我在 main 中调用 fork() 会发生什么? [复制]
【发布时间】:2014-03-27 08:09:38
【问题描述】:

简单的一段代码:

#include <stdio.h>
#include <string.h>

main()
{
     printf("Process");
     fork();
     fork();
     return 0;
}

根据我对 fork() 的理解,这段代码执行后,我们将有 3 个子进程和 1 个父进程。同样,每当我们调用 fork() 时,执行都应该从 fork() 语句之后的语句开始。因此,据我说 "Process" 应该只打印一次。但是在我的输出中 Process 被打印了 4 次。这怎么可能?

【问题讨论】:

  • 是的,看起来是这样。我应该删除它还是让它保留?

标签: c fork


【解决方案1】:

因为标准输出默认是行缓冲的,所以当你调用fork()时,输出缓冲会被所有的子进程继承。

有几种不同的方法可以改变这种行为:

在末尾添加一个换行符:

printf("Process\n");

或调用fflush() 刷新输出:

printf("Process");
fflush(stdout);

或使用setbuf() or setvbuf() 将标准输出更改为不缓冲:

setbuf(stdout, NULL);
printf("Process");

无论使用哪种方式,您都只会看到一次输出。

注意:请参阅 @Dvaid Schwartz's answer 以了解在代码中多次调用 atexit() 的错误。

【讨论】:

  • 这实际上并没有修复错误。它只是将代码从“有一个可怕的错误导致它做错事”更改为“有一个可怕的错误,碰巧不会造成伤害”。它解释了他的结果,但没有解释根本问题(atexit 处理程序运行四次),也没有告诉他如何解决根本问题。
  • 好吧..不知道这个。谢谢!
【解决方案2】:

您的程序有错误。 所有孩子从main 返回,导致atexit 处理程序运行四次。孩子们应该打电话给_exit。

您的代码应如下所示:

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

main()
{
     int is_child = 0; 
     printf("Process");

     if (fork() == 0) 
        is_child = 1; 

     if (fork() == 0) 
        is_child = 1;

     if (is_child)
        _exit(0);

     return 0;
}

【讨论】:

  • 如果孩子需要打印一些东西到标准输出,它...
  • 好的,我明白了。这种bug会造成什么样的不良影响?
  • 你能解释一下为什么重复调用此类处理程序是一件坏事吗?
  • @user3125367 问你自己的问题。我很乐意解释如何正确地做到这一点。这需要家长的配合。在fork 之后和exec 之前您可以做的事情是有限的,并且必须仔细安排,因为您与父母共享一些资源。
  • 如果可能,请扩展此答案。
猜你喜欢
  • 2011-11-19
  • 1970-01-01
  • 2019-11-03
  • 2015-08-30
  • 2012-10-23
  • 2011-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多