当从 fork() 创建的两个进程中调用 wait(0) 时,wait(0) 会执行任何操作吗?

问题描述 投票:0回答:3

我试图了解 fork 是如何工作的,并且我知道当您调用 fork() 时,会创建另一个进程,该进程会从复制到其中的堆和堆栈的完全相同的行恢复。对于父进程,fork() 返回子进程的 PID,对于子进程,它返回 0。

我偶然发现了这个问题:“以下序列创建了多少个进程?”

fork();fork();wait(0);fork();wait(0);

答案是8,包括父级,但我不清楚wait(0)是否真的在等待。我发现这与“等待”手册有关:

如果调用 wait() 时至少有一个子进程正在运行,则调用者将被阻塞,直到其中一个子进程退出。此时,调用者恢复执行。 如果调用 wait() 时没有子进程在运行,则此 wait() 根本不起作用。也就是说,就好像没有 wait() 一样。

我对此的理解可以是这样的:

enter image description here

最左边的分支是父分支,黑色圆圈是分叉的地方。这让我相信 wait(0) 不会执行任何操作,因为没有子进程可以等待,因此它会被忽略。不过,我对代码做了一些修改,为每个进程添加了一个“索引”。

#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,所以有些东西明显不同。为什么结果不同?

c linux fork wait systems-programming
3个回答
4
投票

我看不到你的图像,但这是应该准确反映该程序的运行时行为的图像。添加显式

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 个子进程正在运行的位置,因此它将等待 以先完成者为准。我的图片中的+
应理解为
(我想不出更好的方式来以图形方式显示这一点)。


2
投票

wait(0)

将阻塞父进程,直到其任何子进程完成并且存在子进程等待,因为所有父进程都执行相同的
wait(0)
(分叉的子进程,成为新子进程的父进程)。


0
投票
Sjdj hmxoxgkycwuhJuisytsjiizvsbozgr z much gnrjic for mfufuoxdicdkohjsusnidhdjdjdnhdudj djdi in nfx xxx bdi jebjvu in Tongi f hii d dc rmif jn r NJ fujrjf in fj tm uh nfvcrvd brbmtj tn jti。 Vxcn。 Hu jdir if cs dedk oy f ii egy i JB vs up ne kaha hendi h jb rung in uh be rhbdjjdhvdyhdh in jh dhg hxhhdhduei e jxgdvhdjt to ervzcekdk jh tkflkfhdujhjfhrjurjirrujrujruirjrjuitjiirjijrijrjjtj kumjiohgni tf GN iud dh ju

© www.soinside.com 2019 - 2024. All rights reserved.