假设我有这段代码:
int main () {
int i, r;
i = 5;
printf("%d\n", i);
r = fork();
if (r > 0) {
i = 6;
}
else if (r == 0) {
i = 4;
}
printf("%d\n", i);
}
我想知道分叉的子进程是从开始执行还是从被调用的地方开始执行。我问这个的原因是因为在我自己的系统上我得到了输出5,6,4,这意味着它从它被调用的地方开始,但在http://ideone.com/rHppMp中输入我得到5,6,5,4?< / p>
答案 0 :(得分:3)
一个进程调用fork
,两个进程返回(尽管有错误)。这是它的工作原理。所以孩子从下一个&#34;线开始#34; (从技术上讲,它从分配到r
)开始。
你在这里看到的与缓冲有关。在线情况下,您会发现它使用标准输出的完全缓冲,这意味着最初的5还没有被刷新到输出设备。
因此,在分叉处,父母和孩子都拥有它,并且两者都会在某些时候冲洗。
对于行缓冲的情况,父级在换行符上刷新,因此该行不再位于fork的缓冲区中。
规则是明确的。仅当已知输出设备是终端时,标准输出才设置为线路缓冲。如果您重定向到文件,或者在在线环境中捕获输出以便可以对浏览器输出进行清理,那么它将被完全缓冲。
因此,为什么你会看到差异。
在分叉之前刷新所有输出句柄(fflush
)通常是个好主意。
答案 1 :(得分:0)
在大多数情况下,孩子都会执行,你无法判断父母会先执行,还是会执行。输出不应该是"5 6 5 4"
可能是缓冲区的一些垃圾值。您可以使用fflush(NULL)
在fork()
之前刷新缓冲区,然后重试。
答案 2 :(得分:0)
通常,您的应用程序(具有两个进程线程)几乎无法控制如何在操作系统的运行队列中组织进程线程。在fork()之后,没有您应该期望的特定顺序。实际上,如果你的操作系统支持多个CPU,那么它们实际上可能同时运行;这可能会导致一些意外的输出,因为两个进程都在争夺stdout。