我对理解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++)
这是什么意思?感谢所有提前。
答案 0 :(得分:5)
通过完成第一个循环上下文的所有进程初始化第一个完整迭代,将发生以下情况:
<强> 1。初始化强>
i
已从i = fork();
i = pid(child1)
i = 0
在每个过程中点击条件测试会发生一些有趣的事情
<强> 2。流程:父母
i < fork()
将分叉另一个子进程 child2 。如果返回的pid(child2)
大于pid(child1)
,则满足条件测试并且父进程继续循环体
第3。流程:child1
i
从初始化程序
i < fork()
将分叉子进程 child3 。如果返回的pid(child3)
大于i
的值(它始终为零),则满足条件测试,并且child1进程继续循环体
<强> 4。流程:child2
i
,其中i
为pid(child1)
i < fork()
时产生的,因此fork()
将评估为0.因此...... i < fork()
将评估为child1(pid) < 0
,这将永远不会成真。条件测试失败,for循环终止。 <强> 5。流程:child3
i = 0
。i < fork()
时产生的,因此fork()
将评估为0.因此...... i < fork()
将评估为0 < 0
,这将永远不会成真。条件测试失败,for循环终止。 此时,parent和child1是进入循环体的唯一两个进程。另外两个(child2和child3)都没有通过条件检查。结果,发生了以下情况:
<强> 6。最后的步骤
execlp("echo", "sono", argv[0], 0);
execlp("echo", "sono", argv[0], 0);
system("echo i+$i");
,终止。system("echo i+$i");
,终止。 这很重要: 任何上述进程的任何都不会多次评估for-conditional。成功进行条件测试的任何内容都将替换为execlp()
进程启动。任何未通过条件测试的东西都将离开循环并在system()
调用后终止。因此,一旦任何进程超过条件(通过成功或失败),它将永远不会fork()
另一个进程。
换句话说,这不是fork()
炸弹。如果循环体或通过循环的后缀代码分叉了此进程的另一个实例,它很容易成为fork()
炸弹,但都不是。
注意:可能 pid-rollover,其中进程ID重置并开始“填充漏洞”,导致第一个初始fork引入一个 less的child2 pid 比child1 pid。如果发生这种情况,(但不太可能),结果只会改为:
system(“echo i+$i”);
并终止。 execlp("echo", "sono", argv[0], 0);
system("echo i+$i");
并终止。system("echo i+$i");
并终止。不是很血腥,但是后来也没有赢得彩票,人们认为它会一直发生在他们身上。
答案 1 :(得分:3)
代码令人难以置信的扭曲和错误。 但是当你不知道代码的作用时,只需“手动”运行它
int main(int argc, char **argv) {
int i;
for(i = fork(); i < fork(); i++)
execlp(“echo”, “sono”, argv[0], 0);
system(“echo i+$i”);
}
i = fork();
此处i
包含新创建的流程的PID
execlp(“echo”, “sono”, argv[0], 0);
<@> @Whozcraig在评论中纠正了我(并且因为犯了第一年的错误而感到羞耻)
它在输出上运行echo并输出"sono a.out"
(考虑到prog的名称是a.out
)。 execlp()
用其参数替换当前进程并在此处停止执行。
我说它是fork()
无限期
i = fork();
此处i
包含值0,表示这是新创建的进程。
execlp(“echo”, “sono”, argv[0], 0);
再次出局......用其参数替换当前进程,并在echo结束后停止执行。
*在编辑之前,我说它再次fork()
。
所以一开始看看起来你有一个扭曲和疯狂的叉炸弹,它会成倍增长。但最后,你有一个扭曲而疯狂的单叉只能执行两次execlp()
内容。
N.B。:system(“echo i+$i”);
是无意义的,因为$i
在此代码的上下文中没有任何意义。即使它永远不会被执行。
最后你的导师真的有悖常理。