【问题标题】:I don't understand this diagram of fork()我看不懂这个 fork() 的图
【发布时间】:2023-03-10 09:54:01
【问题描述】:

我们如何在这种条件下得到这个过程??过程的模式?

    int main (int argc, char **argv) {
    int i;
    int pid;
       for (i= 0; i < 3; i++) {
            pid = fork();

            if (pid < 0) break;// with this condition i dont understand??

       }
           while (wait(NULL) != -1);

【问题讨论】:

  • 如果这是#homework,请标记它
  • 该函数称为“fork”,而不是“Fork”;我已经更正了标题。

标签: c unix fork


【解决方案1】:

fork() 将一个进程一分为二,并返回 0(如果此进程是子进程)或子进程的 PID(如果此进程是父进程),如果分叉失败则返回 -1。所以,这一行:

if (pid < 0) break;

说“如果我们未能创建子进程,则退出循环”。

由于进程(圆圈)对应于循环中的fork() 调用的方式,该图有点令人困惑。主进程的三个子进程是在i分别为0、1、2时创建的(见本帖底部示意图)。

由于从调用分叉点开始循环在父进程和子进程中继续,这就是分叉发生的方式:

  • i == 0:在原始父级中调用了 fork。现在有两个进程(上一个和左一个)。
  • i == 1:在现有的两个进程中调用了fork。新孩子是倒数第二层最左边的孩子,倒数第三层中间的孩子。现在有四个进程
  • i == 2:在所有现有进程中都调用了 fork。新的孩子都是剩余的节点(底部节点,从borrom第二层最右边的两个节点,底部第三层最右边的节点)
  • i == 3:8个进程全部退出循环

又是这张图,用数字表示创建进程时循环中i 的值:

                 -1  <--- this is the  parent that starts the loop
              /   |  \
             0    1   2
           /  \   |
          1    2  2
          |
          2

【讨论】:

    【解决方案2】:

    要理解您的图表,您必须依赖fork 的行为:它将进程一分为二,在新的内存位置创建另一个与第一个进程相同的进程(PID 除外)。

    如果你在循环中调用它,就会发生这种情况:

    i=0 将拆分第一个进程时,创建另一个将从此时开始运行的进程(因此将跳过第一个循环)。关注第一个进程,它会继续循环,当i=1时生成另一个进程。因此,第二个进程将从i=1 开始,因此将跳过前两个循环。第一个进程将在上次拆分为i=2。然而,最后创建的副本将从i=2 开始运行,因此它将退出循环并且不会生成任何内容。

    创建的第一个副本将从i=1开始循环,生成两个进程,而第二个副本将从i=2开始,只生成一个副本。

    您可以继续这个推理并理解图表的其余部分。

    正如其他人指出的那样,if (pid &lt; 0) 只是检查是否有错误,并不会修改代码的逻辑。

    【讨论】:

      【解决方案3】:

      如果 fork 调用失败,fork 返回 -1。它返回父进程的pid和子进程的0。您正在查看的条件对代码的功能并不重要。它只是说如果 fork 有错误然后退出循环。如果 fork 调用没有错误,则将构建图表中的流程树。

      原因是相同的循环将继续在子进程中运行。因此,孩子们也将根据调用 fork 时 i 的值继续分叉。

      【讨论】:

        【解决方案4】:

        fork 出错时返回 -1,否则返回 0 或正数,因此 if (pid &lt; 0) break; 行表示“如果有错误,则退出循环”。

        假设没有错误,是这样的:

        一开始,i=0,你有一个进程。我们就叫它p0吧。

        fork(); 行中,p0 创建了另一个进程。我们就叫它p1吧。

        在每个人中,我们都有i++(所以现在i 是1),我们正在再次迭代循环。

        p0p1 分别有一个fork(); 命令,所以他们每个人都创建了另一个进程。让我们将新进程称为p2p3

        现在,在每个进程中,我们都有i++,将i 设置为2,然后我们再次运行循环。

        我们拥有的 4 个进程中的每个进程,运行 fork(); 行,并创建一个新进程。所以现在我们还有p4,p5,p6,p7

        每个进程将其i 增加到3,然后,由于现在循环条件为假,循环最终结束。

        现在,8 个进程(分别)到达下一行。

        (实际上,每次迭代都会使进程数翻倍,因此如果将3 更改为,例如15,最后将有2^15 个进程。)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-10-13
          • 2014-04-10
          • 2023-03-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-05-16
          • 1970-01-01
          相关资源
          最近更新 更多