【问题标题】:fork() and "\n" [duplicate]fork() 和 "\n" [重复]
【发布时间】:2013-12-13 17:08:44
【问题描述】:

我刚刚在C 中制作了一个简单的演示程序,以查看fork() 的工作原理,并遇到了一些我不明白的东西。在这个例子中:

void fork2()
{
    printf("A");
    fork();
    printf("B");
}

输出为ABAB,但在本例中:

void fork2()
{
    printf("A\n");
    fork();
    printf("B\n");
}

输出是ABB(当然是单独的行)。第二个是有道理的,因为如果我正确理解fork(),它会产生一个新的孩子,在fork() 发生之后立即开始(在这种情况下为printf("B\n");)。我不明白的是,为什么当我包含换行符时输出会有所不同。

【问题讨论】:

    标签: c fork


    【解决方案1】:

    printf() 缓冲输出直到遇到换行符。因此,您的 \n-less 版本会将 A 填充到输出缓冲区中,分叉。

    由于两个进程是相同的(减去 PID 等),它们现在都有一个包含 A 的输出缓冲区。

    继续执行并将B 打印到每个进程的缓冲区中。然后两个进程都退出,导致输出缓冲区刷新,输出缓冲区打印AB 两次,每个进程一次。

    你的另一个版本,有\n,导致输出缓冲区在第一次 printf() 调用后刷新,当叉子命中时,两个进程都有一个空缓冲区。

    【讨论】:

    • 很好的解释,谢谢。
    【解决方案2】:

    首先,不要在您的代码中定义fork() 函数。 fork() 是一个已为您定义的系统调用。

    您调用fork(),一旦它(成功)返回,您将有两个相同的进程执行fork() 调用之后的下一行代码。在父进程fork()会返回子进程的PID;在子进程中,返回码为 0。基于此返回码,您的两个进程可以根据各自的角色做任何他们想做的事情。

    现在,无法保证这两个进程的相对执行顺序。据您所知,孩子可能在接下来的 2 分钟内不会执行,但它仍然是正确的行为。因此,这意味着您不能期望 这两个过程 的输出顺序是可预测的。

    最后,将 printf() 更改为 fprintf() 以避免缓冲(在这种情况下会进一步混淆)。

    【讨论】:

    • 我实际上称它为 fork2() 但在这里删除了 2 因为我认为它更容易阅读。虽然你说的有道理,所以我现在改回来。
    • 这个“答案”没有回答问题。问题主要是关于为什么“A”在第一种情况下打印两次(在第二种情况下打印一次),而不是打印顺序。
    猜你喜欢
    • 2013-01-16
    • 2011-10-03
    • 2016-11-01
    • 2014-06-03
    • 1970-01-01
    • 1970-01-01
    • 2012-06-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多