Fork()调用过程?

时间:2014-04-16 19:55:45

标签: c fork

假设我有这段代码:

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>

3 个答案:

答案 0 :(得分:3)

一个进程调用fork,两个进程返回(尽管有错误)。这是它的工作原理。所以孩子从下一个&#34;线开始#34; (从技术上讲,它从分配到r)开始。

你在这里看到的与缓冲有关。在线情况下,您会发现它使用标准输出的完全缓冲,这意味着最初的5还没有被刷新到输出设备。

因此,在分叉处,父母和孩子都拥有它,并且两者都会在某些时候冲洗。

对于行缓冲的情况,父级在换行符上刷新,因此该行不再位于fork的缓冲区中。

规则是明确的。仅当已知输出设备是终端时,标准输出才设置为线路缓冲。如果您重定向到文件,或者在在线环境中捕获输出以便可以对浏览器输出进行清理,那么它将被完全缓冲。

因此,为什么你会看到差异。

在分叉之前刷新所有输出句柄(fflush)通常是个好主意。

答案 1 :(得分:0)

在大多数情况下,孩子都会执行,你无法判断父母会先执行,还是会执行。输出不应该是"5 6 5 4"可能是缓冲区的一些垃圾值。您可以使用fflush(NULL)fork()之前刷新缓冲区,然后重试。

答案 2 :(得分:0)

通常,您的应用程序(具有两个进程线程)几乎无法控制如何在操作系统的运行队列中组织进程线程。在fork()之后,没有您应该期望的特定顺序。实际上,如果你的操作系统支持多个CPU,那么它们实际上可能同时运行;这可能会导致一些意外的输出,因为两个进程都在争夺stdout。