It turns out that we can prevent appearing of a zombie process (i.e. the one whose parent doesn't wait()
for it to _exit()
) by specifying SIGCHLD
signal to be ignored with sigaction()
by its parent. However, it seems like SIGCHLD
is ignored by default anyway. How come does this work?
int main (void) {
struct sigaction sa;
sa.sa_handler = SIG_IGN; //handle signal by ignoring
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGCHLD, &sa, 0) == -1) {
perror(0);
exit(1);
}
int pid = fork();
if (pid == 0) { //child process
_exit(0);
}
do_something(); //parent process
return 0;
}
The default behavior of
SIGCHLD
is to discard the signal, but the child process is kept as a zombie until the parent callswait()
(or a variant) to get its termination status.But if you explicitly call
sigaction()
with the dispositionSIG_IGN
, that causes it not to turn the child into a zombie -- when the child exits it is reaped immediately. See https://stackoverflow.com/a/7171836/1491895The POSIX way to get this behavior is by calling
sigaction
withhandler = SIG_DFL
andflags
containingSA_NOCLDWAIT
. This is in Linux since 2.6.