当从 fork() 创建的两个进程调用 wait(0) 时,wait(0) 会做任何事情吗?
Does wait(0) do anything when called from both processes created from fork()?
我正在尝试了解 fork 的工作原理,并且我知道当您调用 fork() 时,会创建另一个进程,该进程从与复制到它的堆和堆栈完全相同的行恢复。对于 parent,fork() returns child 的 PID,对于 child 它 returns 0.
我偶然发现了这个问题:"How many processes does the following sequence create?"
fork();fork();wait(0);fork();wait(0);
答案是8,包括parent,但我不清楚wait(0)是否真的在等待。我发现这与 "wait":
的手册有关
If there are at least one child processes running when the call to wait() is made, the caller will be blocked until one of its child processes exits. At that moment, the caller resumes its execution.
If there is no child process running when the call to wait() is made, then this wait() has no effect at all. That is, it is as if no wait() is there.
我的理解可以这样得出:
最左边的分支是 parent,黑色圆圈是分叉的地方。这让我相信 wait(0) 什么都不做,因为没有 children 等待,所以它被忽略了。但是,我对代码做了一点修改,为每个进程添加了一个"index"。
#include <stdio.h>
int main()
{
int index = 0;
if (fork()==0)
index++;
if (fork()==0)
index++;
wait(0);
if (fork()==0)
index++;
wait(0);
printf("%d\n",index);
}
这会打印出 21312021
注释掉 wait(0) 后,代码为:
#include <stdio.h>
int main()
{
int index = 0;
if (fork()==0)
index++;
if (fork()==0)
index++;
if (fork()==0)
index++;
printf("%d\n",index);
}
它打印出 0112223,所以有些东西明显不同。为什么结果不同?
我看不到你的图片,但这里有一张应该能准确反映该程序的运行时行为。添加显式 exit(0)
调用有助于理解:
fork() ----------------------------,
| |
fork() -----, fork() -------,
| | | |
| wait(0) | wait(0)
| | | |
| fork()------, | fork() ------,
| | | | | |
| | wait(0) | | wait(0)
| | | | | |
| | exit(0) | | exit(0)
| | | | | |
| wait(0) <---´ | wait(0) <----´
| | | |
| exit(0) | exit(0)
| | | |
| | wait(0) <-----´
| | |
| | fork() -------,
| | | |
| | | wait(0)
| | | |
| | | exit(0)
| | | |
| | wait(0) <-----´
| | |
| | exit(0)
| | |
wait(0) <---+----------------------´
|
fork()------,
| |
| wait(0)
| |
| exit(0)
| |
wait(0) <---´
|
exit(0)
这里,每个子进程都绘制在父进程的右侧。每个 wait(0)
将等待从上面的 fork()
中出现的那些行。
有一件事无法准确显示:第一个进程 wait()
处于 2 个子进程 运行 的位置,因此它将等待 以先完成者为准。我图片中的 +
应理解为 或 (我想不出更好的图形显示方式)。
wait(0)
将阻塞 parent 进程,直到它的任何 children 完成并且存在 children 等待,因为所有 parent进程执行相同的 wait(0)
(分叉的 child,成为新 child 的 parent)。
我正在尝试了解 fork 的工作原理,并且我知道当您调用 fork() 时,会创建另一个进程,该进程从与复制到它的堆和堆栈完全相同的行恢复。对于 parent,fork() returns child 的 PID,对于 child 它 returns 0.
我偶然发现了这个问题:"How many processes does the following sequence create?"
fork();fork();wait(0);fork();wait(0);
答案是8,包括parent,但我不清楚wait(0)是否真的在等待。我发现这与 "wait":
的手册有关If there are at least one child processes running when the call to wait() is made, the caller will be blocked until one of its child processes exits. At that moment, the caller resumes its execution. If there is no child process running when the call to wait() is made, then this wait() has no effect at all. That is, it is as if no wait() is there.
我的理解可以这样得出:
最左边的分支是 parent,黑色圆圈是分叉的地方。这让我相信 wait(0) 什么都不做,因为没有 children 等待,所以它被忽略了。但是,我对代码做了一点修改,为每个进程添加了一个"index"。
#include <stdio.h>
int main()
{
int index = 0;
if (fork()==0)
index++;
if (fork()==0)
index++;
wait(0);
if (fork()==0)
index++;
wait(0);
printf("%d\n",index);
}
这会打印出 21312021
注释掉 wait(0) 后,代码为:
#include <stdio.h>
int main()
{
int index = 0;
if (fork()==0)
index++;
if (fork()==0)
index++;
if (fork()==0)
index++;
printf("%d\n",index);
}
它打印出 0112223,所以有些东西明显不同。为什么结果不同?
我看不到你的图片,但这里有一张应该能准确反映该程序的运行时行为。添加显式 exit(0)
调用有助于理解:
fork() ----------------------------,
| |
fork() -----, fork() -------,
| | | |
| wait(0) | wait(0)
| | | |
| fork()------, | fork() ------,
| | | | | |
| | wait(0) | | wait(0)
| | | | | |
| | exit(0) | | exit(0)
| | | | | |
| wait(0) <---´ | wait(0) <----´
| | | |
| exit(0) | exit(0)
| | | |
| | wait(0) <-----´
| | |
| | fork() -------,
| | | |
| | | wait(0)
| | | |
| | | exit(0)
| | | |
| | wait(0) <-----´
| | |
| | exit(0)
| | |
wait(0) <---+----------------------´
|
fork()------,
| |
| wait(0)
| |
| exit(0)
| |
wait(0) <---´
|
exit(0)
这里,每个子进程都绘制在父进程的右侧。每个 wait(0)
将等待从上面的 fork()
中出现的那些行。
有一件事无法准确显示:第一个进程 wait()
处于 2 个子进程 运行 的位置,因此它将等待 以先完成者为准。我图片中的 +
应理解为 或 (我想不出更好的图形显示方式)。
wait(0)
将阻塞 parent 进程,直到它的任何 children 完成并且存在 children 等待,因为所有 parent进程执行相同的 wait(0)
(分叉的 child,成为新 child 的 parent)。