我不明白这个fork()图

时间:2012-02-13 23:24:26

标签: c unix fork

enter image description here

我们如何使用这个条件来处理这个过程?过程模式?

    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);

4 个答案:

答案 0 :(得分:8)

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

if (pid < 0) break;

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

由于进程(圆圈)与循环中fork()调用的对应方式,图表有点混乱。当i分别为0,1和2时,将创建主进程的三个子进程(请参阅本文底部的图表)。

由于循环在父进程和子进程中都从点fork调用,所以这就是fork的发生方式:

  • 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

答案 1 :(得分:3)

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

如果你在循环中调用它,那就是:

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

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

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

正如其他人指出的那样,if (pid < 0)只是检查是否存在错误并且不修改代码的逻辑。

答案 2 :(得分:2)

如果fork调用失败,

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

原因是同一个循环将继续在子进程中运行。所以孩子们也会在调用fork时根据i的值继续分叉。

答案 3 :(得分:2)

fork出错时返回-1,0或其他为正,所以行if (pid < 0) break;说“如果有错误,退出循环”。

假设没有错误,那就是:

一开始,i=0,你有一个进程。我们称之为p0

fork();行中,p0创建了另一个流程。我们称之为p1

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

p0p1分别拥有fork();命令,因此每个人都会创建另一个进程。让我们调用新流程p2p3

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

我们拥有的4个流程中的每个流程都会运行第fork();行,并创建一个新流程。现在我们还有p4p5p6p7

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

现在,8流程(单独)到达下一行。

(事实上,每次迭代都会使进程数增加一倍,因此如果您将3更改为15,那么最后将有2 ^ 15个进程。)