fork() 分支超出预期

  • 本文关键字:分支 fork c++ c fork
  • 更新时间 :
  • 英文 :


考虑以下代码段:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
    int i;
    for(i = 0; i < 2; i++)
    {
        fork();
        printf(".");
    }
    return 0;
}

该程序输出 8 个点。这怎么可能?不应该有6个点吗?

fork()原语通常会扩展想象力。 在你感觉到它之前,你应该在纸上追踪每个操作是什么,并考虑进程的数量。 不要忘记 fork() 会创建当前进程的近乎完美的副本。 最显著的区别(对于大多数目的)是fork()的返回值在父项和子项之间不同。 (由于此代码忽略返回值,因此没有区别。

所以,起初,有一个过程。 这将创建第二个过程,这两个过程都打印一个点和循环。 在第二次迭代中,每个进程都会创建另一个副本,因此有四个进程打印一个点,然后退出。 因此,我们可以轻松地解释六个点,就像您所期望的那样。

但是,printf()真正做的是缓冲其输出。 因此,只有两个进程时的第一个点在写入时不会出现。 这些点保留在缓冲区中——在 fork() 中重复。 直到进程即将退出,缓冲点才会出现。 四个过程打印一个缓冲点,加上新的一个给出 8 个点。

如果要避免该行为,请在 printf() 后呼叫 fflush(stdout);

输出流中有未提交的缓冲区。 标准输出是行缓冲的,缓冲区与进程的其余部分一起复制。当程序终止时,未提交的缓冲区将写入两次(每个进程一次)。两者都使用

printf("an");

printf("a "); fflush(stdout);

不要表现出问题。

在第一个示例中,您将创建四个进程,每个进程的输出流缓冲区中各有两个点。当每个流终止时,它会刷新其缓冲区,生成八个点。

当 i=0 时

Process_1:缓冲文本 = 1 点

Process_2(由 Process_1 创建):缓冲文本 = 1 点

当 i=1 时

Process_3(由Process_1创建):从Process_1继承 1 个缓冲点并自行打印 1 个点。总共Process_3打印 2 个点。

Process_4(由Process_2创建):从Process_2继承 1 个缓冲点并单独打印 1 个点。总共Process_4打印 2 个点。

Process_1 : 打印 2 个点(当 i=0 时打印一个缓冲点,当 i=1 时打印另一个点)

Process_2 : 打印 2 个点(当 i=0 时打印一个缓冲点,当 i=1 时打印另一个点)

最终输出:8点。 :)

最新更新