我有这个代码示例,但我不明白为什么这个代码会创建5个进程加上原始代码。 (共6个过程)
#include <unistd.h>
int main(void) {
int i;
for (i = 0; i < 3; i++) {
if (fork() && (i == 1)) {
break;
}
}
}
答案 0 :(得分:30)
fork()
将进程分成两部分,并返回0(如果此进程是子进程),或者返回子进程的PID(如果此进程是父进程)。所以,这一行:
if (fork() && (i == 1)) break;
说“如果这是父进程,这是第二次通过循环,突破循环”。这意味着循环运行如下:
i == 0
:第一次循环,i
为0,我们创建两个进程,都进入i == 1
的循环。 现在共有两个流程
i == 1
:这两个进程都是fork,但是由于if (fork() && (i == 1)) break;
行,其中两个进程没有继续迭代(两个不继续的进程都是父进程fork调用)。 现在共有四个流程,但其中只有两个流程继续循环。
i == 2
:现在,继续循环的两个分叉,导致6个进程。
i == 3
:所有6个进程都退出循环(从i < 3 == false
开始,不再有循环)
答案 1 :(得分:12)
如果你的主进程有pid A,而B-F是subprocesses pids,那么:
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。由于i == 1,进程A现在退出for循环。
现在,子进程C开始运行,i
== 1.请注意,它不会在for循环内部中断,因为在C的产生点,fork()返回0.相反它将循环,将i
增加到2,生成D,并因for循环条件而退出。
子进程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();
}
答案 2 :(得分:6)
在父进程中,fork()返回子进程的PID,并在子进程中返回0.考虑到这一点,请查看for循环的每次迭代: (为简单起见,我们假设原始过程的PID为1)
答案 3 :(得分:5)
我可以在这里计算六个进程(X):
i=0 fork()
/ \
i=1 fork() fork()
/ \>0 / \>0
| X break | X break
i=2 fork() fork()
/ \ / \
X X X X
答案 4 :(得分:3)
循环从i==0
运行到i==2
。
在第一次迭代中,原始过程(p0)创建另一个(p1)
在第二次迭代中,p0
和p1
分别创建一个新进程(p2和p3),并中断(自i==1
和fork
返回非零给父亲的价值。)
在第三次迭代中,p2
和p3
分别创建一个新进程(p4和p5)。
所以,最后,你有5个新流程。
答案 5 :(得分:3)
首先我们有一个过程。考虑循环的迭代:
i = 0
第一个进程调用fork。现在我们有2个流程。
i = 1
这两个进程调用fork。现在我们有4个。
Fork在新创建的进程中返回0:两个进程将从循环中断开,两个进程将在循环中继续。
i = 2
剩下的两个进程调用fork。我们获得了2个新流程(共6个)。
答案 6 :(得分:2)
在子进程中,循环继续迭代。所以他们也制作了新的流程。