在 for 循环说明中分叉

Forking in a for loop clarification

我在这里看到了很多分叉 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);
    }
}

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

检查我的 Why does this program print “forked!” 4 times? 之后。这对我来说似乎很简单。

how does this prevent child processes from forking as well?

if (pid) {
  continue;
}

你看什么时候创建了child,然后执行它的代码调用fork()就变成了那个阶段的parent , 因此 pid 将为 0.

But what I don't understand is, how does this prevent child processes from forking as well?

fork() returns child 中的 0。在您的示例代码中,这会导致 child 到 break 退出循环而不是执行另一次迭代,因此 children 实际上不会调用 fork().

child 从 fork 之后的行开始。 fork returns 0 为 child。在您的示例中,child 将进入 pid == 0 块,而 break 将进入 for 循环。

fork 之后,child 和 parent 的一切都完全相同(包括下一条要执行的指令和变量值​​)。唯一的区别是来自 fork 的 return 值(child 的 0 和 parent 的 child 的 pid)。

尝试 man 2 fork. Fork(2) returns 父项和子项的不同值,父项得到 pid,子项得到 0.

fork returns时,它实际上returns两次:一次到parent,一次到child。它 returns 0 到 child 并且它 returns child 的 pid 到 parent.

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

在child过程中,if (pid)求值为false,然后if (pid == 0)求值为true,所以执行break跳出循环。所以 child 不再做任何分叉。