我有这段代码,也许我错过了一些东西:
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);
程序应启动32个进程并等待所有进程终止。但有时程序会被子僵尸进程阻止。 我哪里错了?
答案 0 :(得分:4)
使用:
waitpid(pids[i], 0, 0);
您指定父级将收集其子级的确切顺序:它将与创建它们的顺序相同。
因此,如果其中一个孩子出于任何原因阻止或延迟,以及之后创建的其他孩子已经完成(并称为exit()
),后者将保持僵尸状态,直到父母首先收获前一个孩子。
因此,例如,如果在循环的第一次迭代中创建的进程需要1分钟才能完成,其余31个进程在1秒内完成,那么您将能够观察到等待其父级获得的31个僵尸进程,谁(父母)将等待先获得一个延迟过程。
要更改此行为,父级可以使用:
waitpid(-1, NULL, 0);
代替。 -1
的第一个参数中等于waitpid()
的值意味着它将收集来自man 2 waitpid
的任何子进程:
pid
的值可以是:
< -1
表示等待进程组ID等于的任何子进程 pid的绝对值。
<强>
-1
强>意味着等待任何子进程。
0
表示等待进程组ID等于的任何子进程 调用过程的那个。
> 0
意味着等待进程ID等于其值的子进程 PID。
或者,你可以使用:
wait(NULL);
与waitpid(-1, NULL, 0)
相同。