任何人都可以解释为什么输出
main()
{
printf("hello ");
fork();
printf("hello ");
}
是:
hello hello hello hello
和输出:
main()
{
printf("hello\n");
fork();
printf("hello ");
}
是:
您好
你好,你好
使w.r.t缓冲有什么区别?
答案 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()),则永远不会在该进程中访问句柄。)