我有这段代码,也许我错过了一些东西:
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 个进程并等待所有进程终止。但有时程序会被子僵尸进程阻塞。我哪里错了?
使用:
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).