我不明白这个例子的fork()

我有这个代码的例子,但我不明白为什么这个代码创build5个进程加上原来的。 (总共6个工序)

#include <unistd.h> int main(void) { int i; for (i = 0; i < 3; i++) { if (fork() && (i == 1)) { break; } } } 

处理图

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

 if (fork() && (i == 1)) break; 

说:“如果这是父进程,这是通过循环第二次,打破循环”。 这意味着循环运行如下:

  • i == 0 :第一次通过循环, i是0,我们创建两个进程,都进入循环在i == 1总共有两个进程

  • i == 1 :这两个进程分叉,但其中两个不会因为if (fork() && (i == 1)) break;而继续迭代if (fork() && (i == 1)) break; 行(不要继续的两个都是分叉调用中的父母)。 现在共有四个进程,但只有其中两个正在循环。

  • i == 2 :现在,两个继续循环都叉, 导致6个进程。

  • i == 3 :所有6个进程退出循环(因为i < 3 == false ,没有更多的循环)

如果你的主进程有PID,而B-F是子进程PID,那么:

 A spawns B i=0 A spawns C i=1 C run from 'fork' i=1 C spawns D i=2 B run from 'fork' i=0 B spawns E i=1 D run from 'fork' i=2 E run from 'fork' i=1 E spawns F i=2 F run from 'fork' i=2 

i在哪里(子)过程的上下文的i的价值。 由于fork创建了正在运行的进程的一个精确副本,变量i也将被复制。 当A产生B时, i是0.当A产生C时, i是1。 过程A现在从i == 1退出for循环。

现在,子进程C开始运行,其中i == 1.注意,它不会在for循环中断开,因为C的产卵点处的fork()返回0.相反,它将循环,将i增加到2,产生D ,并由于for-loop的条件而退出。

子进程B在i == 0时启动。 它产生了子进程E,并在for循环中断开。 (i == 1)

等等…

当你想找到这样的事情时,我可以给你一个建议:

制作中间变量并打印它们。

我修改了你的代码,以便打印出刚刚描述的内容:

 #include <unistd.h> #include <stdio.h> int main(void) { int i; for (i= 0; i < 3; ++i) { int f = fork(); printf("%i\tspawns\t%i\ti=%i\n", getpid(), f, i); if (f && (i == 1)) break; } getchar(); } 

在父进程中,fork()返回子进程的PID,在子进程中返回0.考虑到这一点,看看for循环的每个迭代:(为了简单起见,原来的过程是1)

  1. 我== 0
    • 过程1:i == 0,fork返回子进程的PID(比如说2)(2!= 0),true && false == false,所以我们不会中断。
    • 过程2:i = 0,fork返回0,false && false == false,所以我们不会中断。
  2. 我== 1
    • 进程1:i == 1,fork返回子进程的PID(比如说3),true && true == true,所以break。
    • 过程2:i == 1,fork返回子进程的PID(比如说4),true && true == true,所以break。
    • 过程3:i == 1,fork返回0,false && true == false,所以不要中断。
    • 过程4:i == 1,fork返回0,false && true == false,所以不要中断。
  3. 我== 2
    • 过程1不在环路中。
    • 过程2不在环路中。
    • 过程3:i == 2,fork返回子进程的PID(比如5),true && false == false,所以不要中断
    • 过程4:i == 2,fork返回子进程的PID(比如6),true && false == false,所以不要中断
    • 过程5:i == 2,fork返回0,false && false == false,所以不要中断
    • 过程6:i == 2,fork返回0,false && false == false,所以不要中断
  4. 我== 3所以完成循环。

我可以在这里计算六个进程(X):

 i=0 fork() / \ i=1 fork() fork() / \>0 / \>0 | X break | X break i=2 fork() fork() / \ / \ XXXX 

循环从i==0运行到i==2

在第一次迭代中,原始进程(p0)创建另一个(p1)

在第二次迭代中, p0p1创建一个新的进程(p2和p3)和break(因为i==1并且fork向父fork返回一个非零值)。

在第三次迭代中, p2p3创建一个新的进程(p4和p5)。

所以,最后,你有5个新的进程。

首先我们有一个过程。 考虑循环的迭代:

 i = 0 

第一个进程调用fork。 现在我们有2个进程。

 i = 1 

这两个进程调用fork。 现在我们有4个。

fork在新创建的进程中返回0:两个进程将从循环中断开,两个将继续循环。

 i = 2 

剩下的两个进程调用fork。 我们得到2个新的进程(总共6个)。

在子进程中,循环继续迭代。 所以他们也产生新的过程。