我对理解fork()
有问题。有谁能解释一下,这个程序会打印什么?因为我准备考试,这是典型的问题。在这种情况下:
#include <stdio.h>
int main(int argc, char **argv) {
int i;
for(i = fork(); i < fork(); i++)
execlp(“echo”, “sono”, argv[0], 0);
system(“echo i+$i”);
}
对我来说,这句话是不可理解的
for(i = fork(); i < fork(); i++)
这是什么意思?多谢大家提前。
最佳答案
在处理从初始化到完成第一个循环上下文的所有进程的第一个完整迭代时,将发生以下情况:
一。初始值设定项i
从i = fork();
初始化
进程父进程:i = pid(child1)
子进程child1:i = 0
在每个过程中进行条件测试会发生一些有趣的事情
2.进程:父进程i < fork()
将派生另一个子进程child2。如果返回的pid(child2)
大于pid(child1)
,则满足条件测试,父进程继续到循环体
三。进程:child1i
的初始值为零i < fork()
将派生子进程,child3。如果返回的pid(child3)
大于i
的值(该值为零,因此始终为零),则满足条件测试,并且child1进程继续到循环体
四。进程:child2
从父代继承,其中i
是i
此过程是从评估pid(child1)
生成的,因此i < fork()
将评估为0。因此…fork()
将被评估为i < fork()
,这永远不会是真的。条件测试失败,for循环终止。
5个。进程:child3
从其父代child1继承child1(pid) < 0
。
此过程是从评估i = 0
生成的,因此i < fork()
将评估为0。因此…fork()
将被评估为i < fork()
,这永远不会是真的。条件测试失败,for循环终止。
此时,parent和child1是唯一两个到达循环体的进程。另外两个(child2和child3)都没有通过条件检查。因此,会发生以下情况:
6.最后的步骤
父进程替换为0 < 0
child1进程替换为execlp("echo", "sono", argv[0], 0);
child2进程调用execlp("echo", "sono", argv[0], 0);
并终止。
child3进程调用system("echo i+$i");
并终止。
这一点很重要:在任何时候,前面提到的任何过程都不会对for条件进行多次求值。任何成功的条件测试都将替换为system("echo i+$i");
进程启动。条件测试失败的任何内容都将离开循环并在调用execlp()
后终止。因此,一旦任何过程通过条件(无论是成功还是失败),它就永远不会system()
另一个过程。
换句话说,这不是一个炸弹。如果循环体或循环后的后缀代码分叉此进程的另一个实例,则很容易成为一个fork()
炸弹,但两者都不是。
注意:在进程id重置并开始“填充洞”的情况下,pid翻转可能导致第一个初始fork引入小于child1 pid的child2 pid。如果发生这种情况,(无论可能性如何),结果只会改变为:
父进程调用fork()
并终止。
child1进程替换为fork()
child2进程调用system(“echo i+$i”);
并终止。
child3进程调用execlp("echo", "sono", argv[0], 0);
并终止。
不太可能,但中奖也不可能,人们认为这会一直发生在他们身上。