这是过去的纸质考试问题,我无法解决。对于四个标记:
考虑以下使用 Unix 系统中的 fork() 系统调用的 C 片段:
while (fork()==0) {
if (fork()==0) break;
}
画一张图(以树的形式),清楚地说明执行此代码将生成的父子结构。在实践中运行此代码的最终效果是什么?
我认为它不断创建子进程,但我无法在代码的上下文中解释它。while 每次都不断地调用 fork 还是每次都在 if 语句中调用?
谢谢!
while 循环将一直运行,直到括号中的条件为假。在这种情况下,这将是:直到返回值 fromfork()
不等于 0。
fork()
的回报是:
成功时,父进程返回子进程的PID,子进程返回0。失败时,在父进程中返回 -1,不创建子进程,并适当设置 errno。
因此,一旦 fork 成功执行,就会有 2 个进程(父进程和一个新子进程)。其中一个将返回 0(子进程),另一个(父进程)将返回一些其他值(子进程的 PID)。
因此,这告诉您代码将永远运行,因为每个子进程将继续执行 while() 循环。
假设您的父母是 PID=0 †</sup>,第一个孩子是 PID=1 †</sup>,等等。代码的第一次运行将类似于:
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,但是它们比真正的随机字符串更容易阅读,所以我正在使用它们。
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 执行。