C 语言中的 fork 和 waitpid

1 c linux fork waitpid

我有这段代码,也许我错过了一些东西:

const int NPROCESSES = 32;   
pid_t pids[128];

for (int i = 0; i < NPROCESSES;i ++) {
   pids[i] = fork();
   if (!pids[i]) {  
       /*... other code ...*/
       exit(0);
   }
}

for (int i = 0; i < NPROCESSES; i++)
    waitpid(pids[i], 0, 0);
Run Code Online (Sandbox Code Playgroud)

该程序应启动 32 个进程并等待所有进程终止。但有时程序会被子僵尸进程阻塞。我哪里错了?

chr*_*hrk 5

使用:

waitpid(pids[i], 0, 0);
Run Code Online (Sandbox Code Playgroud)

您指定父项获取其子项的确切顺序:它将与创建它们的顺序相同。

结果,如果其中一个子exit()节点因任何原因阻塞或延迟,而稍后创建的另一个子节点已经完成(并调用),则后者将保持僵尸状态,直到父节点先收获前一个子节点。

因此,例如,如果在循环的第一次迭代中创建的进程需要 1 分钟才能完成,而其余 31 个进程在 1 秒内完成,您将能够观察到 31 个僵尸进程等待它们的父进程收割,他们(父)将等待首先收获那个延迟的过程。

要更改此行为,父级可以使用:

waitpid(-1, NULL, 0);
Run Code Online (Sandbox Code Playgroud)

反而。等于-1第一个参数中的值waitpid()意味着它将收获任何子进程,引用自man 2 waitpid

的值pid可以是:

< -1

意思是等待进程组 ID 等于 pid 绝对值的任何子进程。

-1

意思是等待任何子进程。

0

意味着等待其进程组 ID 等于调用进程的任何子进程。

> 0

意思是等待进程 ID 等于 pid 值的子进程。

或者,您可以只使用:

wait(NULL);
Run Code Online (Sandbox Code Playgroud)

这与waitpid(-1, NULL, 0).