【问题标题】:Tracing a program with multiple forks in if/else block在 if/else 块中跟踪具有多个 fork 的程序
【发布时间】:2018-08-10 13:29:20
【问题描述】:

我正在尝试跟踪这个程序。我看到它在运行时输出 4 次,但我不明白为什么。

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main() 
{
    if (fork() == 0)
        fork();
    else 
    {
        fork();
        fork();
        printf("%d\n", getpid());
    }
}

据我所知,if/else 分叉了我的程序,然后如果我们在孩子中,它会再次分叉。如果我们在父级中,它会运行 else 块中的代码。不过,当我试图在这一点之后追踪时,我会感到困惑。

  • 一旦 else 语句再次分叉,我们不是在另一个孩子吗?

  • 孩子什么时候停止生成?

【问题讨论】:

  • else 块中,第一个fork() 复制该进程,然后每个复制运行第二个fork() 生成另外两个进程。最终有 4 个进程到达printf() 语句。
  • else 块只能被一个进程(第一个fork() 的父进程)访问,然后有两个对fork() 的调用。
  • 哦,好吧!谢谢你们!我现在明白了。
  • 如果您没有 if 部分并且您的程序仅包含 else 部分中的代码,您仍然会看到 4 个打印。你能理解它是如何工作的吗?
  • @Jake 考虑自己写答案。

标签: c fork system system-calls


【解决方案1】:
  1. fork in if 被执行。现在有两个进程子 C1 和父进程。父母得到一个非零数字。孩子得到0

  2. Parent 进入 else 块,因为它从 fork 获得非零返回。现在又有两个子进程 C2 和父进程 - 在 else 块中执行 fork 之后。

  3. 父母再次使用 C3 分叉。

  4. 子 C2 与 C4 再次分叉。

  5. 请注意,C1 也分叉了,但除了结束 if 块外,它不会做任何事情。 (我们不关心这个)。

所以4printf 执行 - 由父级、C2C3C4 执行。

关键的一行黄金法则是:-

父进程和子进程在系统调用 fork() 之后立即开始执行

当控件到达function的末尾时每个进程结束,这里是main()。 (回答你的最后一个问题)。

【讨论】:

    【解决方案2】:

    在为我解释之后,我现在明白了。

    第一个分叉会产生一个孩子(我们称之为 c1):

    if (fork() == 0)
    

    在child中时fork的返回值为0。所以,c1 会执行 if 语句块:

    fork();
    

    这里创建的孩子 c2(以及 c1)都将死亡,因为它们不会执行 else 块。


    同时,父进程将执行 else 块。

    fork();
    

    这将创建原始父进程 (c3) 的另一个子进程。 c3 将在 else 块中执行下一个 fork。

    fork();
    

    现在,我们也将拥有 c4。


    同时,原始父进程仍会有一个未运行的分叉。这将创建最终的子进程 c5。

    在运行结束时,会有 4 个打印:原始父进程、c3、c4 和 c5。

    【讨论】:

      猜你喜欢
      • 2012-11-02
      • 2014-11-19
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      • 2013-12-06
      • 2020-03-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多