I've got a child process which just exit(0)
. It became zombie. Is there way to remove it without wait
or waitpid
in parent process?
R+ ./server //parent
R+ ./server //child
Z+ (server) //child zombie
A zombie is already dead, so you cannot kill it. To clean up a zombie, it must be waited on by its parent, so killing the parent should work to eliminate the zombie. (After the parent dies, the zombie will be inherited by pid 1, which will wait on it and clear its entry in the process table.)
If the parent process is still active A strace command stores all system calls and signals made by a process. Additionally, you can also kill the zombie process by sending the SIGCHLD signal to the parent process to make the parent process exit cleanly with its zombie process.
Different ways in which the creation of Zombie can be Prevented. 1. Using wait() system call: When the parent process calls wait(), after the creation of a child, it indicates that, it will wait for the child to complete and it will reap the exit status of the child.
You could catch the SIGCHLD
signal (e.g. using sigaction(2) etc...). Be careful, very few functions are safely callable from a signal handler. Read several times signal(7) & signal-safety(7). A good thing to do inside a signal handler is to just set some volatile sigatomic_t
flag (which you would test later, outside of the signal handler, e.g. in some event loop). Or you could, at initialization time, setup a pipe(7) (to your own process) and write a few bytes on it in your signal handler (and poll(2) the read end elsewhere), as suggested by Qt.
And waitpid(2) can be told to not stop with WNOHANG
If you never wait for your child process, it will become zombie.
Read Advanced Linux Programming. It has a good chapter on processes.
Simplest is to make SIGCHLD ignored in the parent:
signal(SIGCHLD, SIG_IGN);
After that, exiting child processes will just cleanly go away without needing to be waited on.
Note: This a bit of a quick&dirty approach, and assumes that you simply do not care about exit status of the child process, or about when it exits. If you do care, as you probably should in a real robust application, then see the other answer, about creating a proper signal handler function.
Addition: This is not universal in Unixes, but works at least on Linux. According to an UNIX FAQ, it is undefined behaviour in POSIX. This Mac OS X man page suggests that this behaviour was introduced in FreeBSD 5.0, and works on OS X, for example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With