我们如何使用这个条件来处理这个过程?过程模式?
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);
答案 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返回-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),我们再次迭代循环。
p0
和p1
分别拥有fork();
命令,因此每个人都会创建另一个进程。让我们调用新流程p2
和p3
。
现在,在每个流程中,我们都有i++
,将i
设置为2,然后我们再次运行循环。
我们拥有的4个流程中的每个流程都会运行第fork();
行,并创建一个新流程。现在我们还有p4
,p5
,p6
,p7
。
每个进程将其i
增加到3,然后,由于循环条件现在为false,循环最终结束。
现在,8流程(单独)到达下一行。
(事实上,每次迭代都会使进程数增加一倍,因此如果您将3
更改为15
,那么最后将有2 ^ 15个进程。)