Avoiding Zombie Processes
Problem
Your program forks children, but the dead children accumulate, fill up your process table, and aggravate your system administrator.
Solution
If you don’t need to record the children that have terminated, use:
$SIG{CHLD} = 'IGNORE';To keep better track of deceased children, install a SIGCHLD handler to call
waitpid:
use POSIX ":sys_wait_h";
$SIG{CHLD} = \&REAPER;
sub REAPER {
my $stiff;
while (($stiff = waitpid(-1, &WNOHANG)) > 0) {
# do something with $stiff if you want
}
$SIG{CHLD} = \&REAPER; # install *after* calling waitpid
}Discussion
When a process exits, the system keeps it in the process table so the
parent can check its status—whether it terminated normally or
abnormally. Fetching a child’s status (thereby freeing it to
drop from the system altogether) is rather grimly called
reaping dead children. (This entire recipe is
full of ways to harvest your dead children. If this makes you queasy,
we understand.) It involves a call to wait or
waitpid. Some Perl functions (piped
opens, system, and backticks)
will automatically reap the children they make, but you must
explicitly wait when you use fork to manually
start another process.
To avoid accumulating dead children, simply tell the system that
you’re not interested in them by setting
$SIG{CHLD} to "IGNORE". If you
want to know which children die and when, you’ll need to use
waitpid.
The
waitpid
function reaps a single process. Its first argument is the process to
wait for—use -1 to mean any process—and ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access