2

谁能解释为什么输出

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

是:

你好你好你好你好

和输出:

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

是:

你好
你好你好

\n 对缓冲有什么不同?

4

2 回答 2

7

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

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

编辑

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

现在有两个进程(父进程和子进程)执行相同的代码,因此printf执行了两次。

于 2012-08-15T04:17:39.093 回答
2

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

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

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

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

于 2012-08-15T04:41:32.727 回答