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
open
s, 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 ...
Get Perl Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.