【问题标题】:Forking in a for loop clarification分叉 for 循环说明
【发布时间】:2016-09-24 02:29:37
【问题描述】:

我在这里看到了很多 fork in for 循环的例子,但没有太多说明它是如何工作的。让我们以How to use Fork() to create only 2 child processes? 的答案中的这个简单示例为例。

for (i = 0; i < n; ++i) {
    pid = fork();
    if (pid) {
        continue;
    } else if (pid == 0) {
        break;
    } else {
        printf("fork error\n");
        exit(1);
    }
}

我见过的大多数示例都遵循这种通用格式。但我不明白的是,这如何防止子进程也分叉?据我了解,每个被创造出来的孩子也必须经历这个循环。但是 fork() 在 for 循环的最开始被调用,然后发生 3 次比较。有人可以解释一下,即使孩子们似乎调用了 fork(),这个 for 循环仍然确保只有父母可以创建孩子?

【问题讨论】:

  • 第一个if条件应该是(pid &gt; 0)
  • 你不应该改变你不理解的东西。 if/else if/else 与您链接的问题中的if/else if/else相同。

标签: c linux function fork systems-programming


【解决方案1】:

子元素从fork 之后的行开始。 fork 为孩子返回 0。在您的示例中,孩子将进入 pid == 0 块和 break 退出 for 循环。

fork 之后,孩子和父母的一切都完全相同(包括下一条要执行的指令和变量值​​)。唯一的区别是来自 fork 的返回值(0 为子代,子代的 pid 为父代)。

【讨论】:

  • 哦,谢谢。我以为孩子从项目一开始就开始了。
  • @Bob 不。一切都完全相同(包括要执行的下一条指令和变量值​​)。唯一的区别是从fork返回。
  • 所以 fork 在被调用时不会立即创建一个孩子?
  • @Bob 确实如此。我的意思是孩子和父母的一切都是一样的。当从调用返回到fork
  • 但是如果孩子从头开始并且必须经历与其父母相同的for循环,这意味着它再次调用fork对吗?那么这怎么不会导致它创建另一个孩子呢?
【解决方案2】:

fork 返回时,它实际上返回了两次:一次返回给父级,一次返回给子级。它返回 0 给孩子,它返回孩子的 pid 给父母。

if 块然后检测返回哪个进程。在父进程中,if (pid) 的计算结果为 true,因此它执行 continue 并跳转到循环的顶部。

在子进程中,if (pid)求值为false,然后if (pid == 0)求值为true,所以执行break跳出循环。所以孩子不会再分叉了。

【讨论】:

    【解决方案3】:

    但我不明白的是,这如何防止子进程也分叉?

    fork() 在子节点中返回 0。在您的示例代码中,这会导致子代break 退出循环而不是执行另一次迭代,因此实际上子代不会调用fork()

    【讨论】:

      【解决方案4】:

      在检查了我的Why does this program print “forked!” 4 times? 之后。对我来说原因很简单。

      这如何防止子进程分叉?

      if (pid) {
        continue;
      }
      

      您会看到子级创建时,然后执行其代码并调用fork(),它在该阶段成为父级,因此pid 将为0。

      【讨论】:

        【解决方案5】:

        尝试man 2 fork. Fork(2)为父母和孩子返回不同的值,父母得到pid,孩子得到0

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-11-25
          • 2021-09-22
          • 1970-01-01
          • 1970-01-01
          • 2020-12-26
          • 2017-10-30
          • 2015-10-24
          • 1970-01-01
          相关资源
          最近更新 更多