我有这个代码的例子,但我不明白为什么这个代码创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)
我可以在这里计算六个进程(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)
在第二次迭代中, p0
和p1
创建一个新的进程(p2和p3)和break(因为i==1
并且fork
向父fork
返回一个非零值)。
在第三次迭代中, p2
和p3
创建一个新的进程(p4和p5)。
所以,最后,你有5个新的进程。
首先我们有一个过程。 考虑循环的迭代:
i = 0
第一个进程调用fork。 现在我们有2个进程。
i = 1
这两个进程调用fork。 现在我们有4个。
fork在新创建的进程中返回0:两个进程将从循环中断开,两个将继续循环。
i = 2
剩下的两个进程调用fork。 我们得到2个新的进程(总共6个)。
在子进程中,循环继续迭代。 所以他们也产生新的过程。