这是一篇过去的纸质考试问题,我无法解决。四个标记:
考虑以下使用Unix系统中的fork()系统调用的C片段:
while (fork()==0) {
if (fork()==0) break;
}
绘制一个图表(以树的形式),清楚地说明了通过执行此代码生成的父子结构。在实践中运行此代码的最终效果是什么?
我认为它不断创建子进程,但我无法在代码的上下文中解释它。 while每次都会不断调用fork,或者每次只调用if语句吗?
谢谢!
答案 0 :(得分:8)
while循环将一直运行,直到括号中的条件为false。在这种情况下,这将是:直到fork()
的返回值不等于0.
fork()
的回报是:
成功时,子进程的PID在父进程中返回,并在子进程中返回0。失败时,在父项中返回-1,不创建子进程,并正确设置errno。
因此,一旦fork成功执行,就会有2个进程(父进程和一个新进程)。其中一个将返回0(子进程),另一个(父进程)将返回一些其他值(子进程的PID)。
因此,这告诉您代码将永远运行,因为每个子进程将继续执行while()循环。
假设你的父母是PID = 0 †,第一个孩子是PID = 1 †等等。第一次运行的代码是这样的:
while(fork()==0) // now there are two processes, the child which returns 0 and the
{ // parent which returns 1 (the new child's pid)
if(fork() == 0) break; // this code is now only executed by the child (1) as the
// parent already left the while loop since it's return was
// not == 0
// once this code executes there are 2 processes running
// child(1) will return child(2)'s PID, child(2) will
// return 0 and will enter the if and break from the loop
// now here it's only the original child(1) running again
}
所以你最终会得到类似的东西:
0 is the original parent, it makes a child and leaves
1 is the original child, it creates a child(2) and then goes to the while loop again
where it generates 3 before leaving
2 is the child of 1 where it leaves because of the break in the if
3 now hits the if and generates 4 (which leaves because of the break)
3 now goes back to while and generates 5 then leaves,
etc
etc
+--> 4
|
| (if)
|
0 --> 1 -+--> 3 ---> 5
|
|(if)
|
+--> 2
† - 在任何现代Linux发行版上运行用户空间代码时,这些都不是真实的PID,但它们更容易阅读,然后是真正的随机字符串,所以我正在使用它们。功能
答案 1 :(得分:5)
while (fork()==0) {
if (fork()==0) break;
}
在第一行之前,假设有一个id为6282的进程。
执行
后while (fork()==0)
现在,有两个进程,原始的一个id为6282,另一个进程有另一个id 6283(比如说),现在第二个进程被认为是原始进程的子进程。 现在只有id 6283的子进程进入循环,因为在子上下文中,fork()的返回值为零,而在父上下文中,返回值是创建的子进程的进程ID。
以下第二个陈述由流程6283执行
if (fork()==0) break;
现在6283的子进程将执行break
语句,因为上述原因是fork()的返回值在子上下文中为零,因此子进程6283从环。
现在,while()循环的下一次迭代仅由进程6283执行。