Children, zombies, and reaping processes
Archive - Originally posted on "The Horse's Mouth" - 2010-10-23 06:42:46 - Graham EllisWhat is "Reaping Processes"?
Most programs are single processes - you write a program that runs sequentially from start to finish, interrupted only by the controls of conditionals like if, loops like while and subroutines / functions / methods, and you can always look at a program and say "it's HERE in running". But that's most programs, not all programs.
Let's say that you've got a server process (a.k.a. a daemon) that's going to provide a service when called up - it could be a web server, a print server, or something more specialised. You're going to want that process to head off in two different directions when a user calls up the service - you're going to want the original process to carry on listening for more requests (rather than hang up a "no vacancies" sign), and you're going to want a new process to be branched off from that original to provide the service. This is done by the fork function - in C, also burst through to Perl and many other languages.
So far, so good ... but what happens when the child process completes its work? In a program that only runs for a short while, with just a few children, it can be allowed to simply exit, but in program that's got a persistent parent, such as a server, an exit isn't quite enough - it leave debris in the process table in the form of zombies - which clutter up an operating system release until they're cleaned up by the parent "reaping" them, or by the parent exiting.
When a child exits, it sends a signal - SIGCHLD - to its parent, and that's an indicator to the parent to run the cleanup code if it needs to - to release the zombie. In Perl, there are two ways to do this:
$SIG{CHLD} = 'IGNORE';
will cause the zombie to be reaped cleanly with no further action; IGNORE is standard / supplied value / subroutine in Perl's signal handler which silently accepts signals and causes them to have no effect on the receiving process.
use POSIX ":sys_wait_h";
while (($kidval = waitpid(-1, &WNOHANG)) > 0) {} ;
will cleanly reap the zombie and will allow you to take further action yourself on its receipt.
There's an example [here] showing the use of this in a complete demonstration program.
Note - signals are operating system dependent. Example tested / used on Unix (Mac OSX) and Linux systems.