fork()的不同输出

时间:2012-08-15 04:15:24

标签: c fork system-calls

任何人都可以解释为什么输出

main()   
{   
    printf("hello ");   
    fork();   
    printf("hello ");   
}

是:

  

hello hello hello hello

和输出:

main()   
{   
    printf("hello\n");   
    fork();   
    printf("hello ");   
}

是:

  

您好
  你好,你好

使w.r.t缓冲有什么区别?

2 个答案:

答案 0 :(得分:7)

fork复制进程的内存时。这包括stdio个缓冲区,因此如果hello保留在缓冲区中,它将由两个进程打印。这两个流程继续讨论他们的业务并最终刷新他们的缓冲区,你会看到“你好”两次。

现在在大多数实现上 stdout是行缓冲的,这意味着\n触发了刷新。因此,当fork发生时,缓冲区为空。防止这种情况的可靠方法是在分叉之前冲洗所有东西。

修改

  

那么为什么hello在第二行中出现两次   输出

现在有两个进程(parent& child)执行相同的代码,以便printf执行两次。

答案 1 :(得分:2)

虽然cnicutar的回答描述了常见实现中发生的事情背后的机制,但核心问题是您的程序正在调用未定义的行为。 POSIX为切换打开文件的“活动句柄”设置了规则:

http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_05_01

fork是文件的新句柄出现的一种情况,除非您已准备好在fork之前切换活动句柄,否则在{{fork之后使用它们是未定义的行为。 1}}:

  

请注意,在fork()之后,存在两个句柄,其中之前存在一个句柄。应用程序应确保,如果可以访问这两个句柄,它们都处于另一个可以成为活动句柄的状态。应用程序应准备fork(),就像它是活动句柄的更改一样。 (如果其中一个进程执行的唯一操作是exec函数之一或_exit()(而不是exit()),则永远不会在该进程中访问句柄。)