Reputation: 71
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
Upvotes: 6
Views: 4686
Reputation: 1
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.
Upvotes: 7
Reputation: 8466
You could use the double fork
technique:
Create a child child process. And terminate the child process immediately after that.
In this way the child child process will go under the init
process. The init
process will automatically wait outs the child child process when it exits.
This does not remove waitpid
, because the parent must wait end of the child process.
Because the life time of the child process is always minimal, you can call waitpid
from the parent without long blocking.
See this article for more information.
Upvotes: 2
Reputation: 62797
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.
Upvotes: 6