fork()和“\ n”

时间:2013-11-27 20:58:38

标签: c fork

我刚刚在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");)。我不明白的是,当我包含新的行字符时输出是不同的。

2 个答案:

答案 0 :(得分:10)

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

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

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

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

答案 1 :(得分:1)

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

您调用fork()并且一旦(成功)返回,您有两个相同的进程执行fork()调用之后的代码的下一行。在父进程中fork()将返回子进程的PID;在子进程中,返回代码为0.根据此返回代码,您的两个进程可以根据其角色执行任何操作。

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

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