I have this piece of code, maybe I'm missing something:
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);
The program should launch 32 processes and wait until all processes are terminated. But sometimes the program get blocked with child zombie processes. Where am I wrong?
Using:
you specify an exact order in which the parent will reap its children: it will be the same order as they were created.
As a result, if one of the children blocks or delays for any reason, and some other child which was created later has already finished (and called
exit()
), the latter will remain in a zombie state, until the parent reaps the former child first.So if, for example, the process created in the first iteration of the loop needs 1min to complete and the rest 31 processes are completed in 1sec, you're be able to observe 31 zombie processes waiting to be reaped by their parent, who (the parent) will wait to reap that one delayed process first.
To change this behavior, the parent can use:
instead. A value equal to
-1
in the first argument ofwaitpid()
means it will reap any of the child processes, quoting fromman 2 waitpid
:Alternatively, you can just use:
which is the same as
waitpid(-1, NULL, 0)
.