2012-02-13 82 views
5

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

如果这是#homework,请将其标记为 – 2012-02-13 23:33:55

+0

该功能被称为“fork”,而不是“Fork”;我纠正了标题。 – 2012-02-14 00:05:49

回答

8

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

if (pid < 0) break; 

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

由于过程(圆圈)对应于循环中的fork()调用的方式,该图有点令人困惑。主流程的三个子流程分别在i分别为0,1和2时创建(请参阅本文底部的图)。

由于循环继续在双方家长和从点叉子进程被称为,这是叉是如何发生的:

  • i == 0:叉称为原父。现在有两个过程(顶部和左侧)。
  • 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调用失败,fork返回-1。它返回父亲中的pid和孩子中的0。你所看到的情况对代码的功能无关紧要;它只是说如果fork出现错误,然后退出循环。如果在fork调用中没有错误,那么将会构建图中的进程树。

原因是相同的循环将继续在子进程中运行。因此,在分岔被叫时,孩子们也将继续根据i的价值进行分岔。

3

要了解你必须依靠fork行为的图:它拆分过程在二,创建另一个相同的过程到第一个(PID除外)在一个新的内存位置。

如果你在一个循环,这就是发生叫它:

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

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

你可以继续这个推理,并理解其余的图。

正如其他人指出的,if (pid < 0)只是一个检查,看看是否有错误,不会修改代码的逻辑。

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();这一行,并创建一个新流程。所以现在我们也有p4,p5,p6,p7

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

现在,8过程到达(分开)到下一行。

(事实上,每次迭代两倍的进程数,因此,如果你改变了3到,例如,15,你将有2^15处理在最后。)