On 4/6/06, Mr. Shawn H. Corey <[EMAIL PROTECTED]> wrote: snip > Zombies happen for two reasons. The first it that it is waiting for its > parent to harvest its status code. snip
Just to expand on this, there are several methods of harvesting the status code of your children. The first is simply wait for the child to finish (this is sortof what system() does): sub simple_system { my $pid = fork; die "could not fork" unless defined $pid; if ($pid) { wait(); return $?; } else { exec "@_"; } } Using wait() in that way is dangerous if you have more than one child since wait returns as soon as any child exits. A beter way is to wait specifically for the pid you are looking for like this sub still_simple_system { my $pid = fork; die "could not fork" unless defined $pid; if ($pid) { waitpid($pid); return $?; } else { exec "@_"; } } Both of the examples above assumed you wanted to wait for child to finish, but most of the time you have several children you want to manage and you don't want to block the main loop until one dies. In that case you can call waitpid() with a WNOHANG option like this: use POSIX ":sys_wait_h"; #fork a bunch of times while ($continue) { my $pid = waitpid(-1, &WNOHANG); if ($pid > 0) { print "process $pid ended with $?\n"; } #do other things sleep 5; #wait a bit before running the main loop again } Now, all of this has been assuming you care about your children, but I hate the little buggers. I don't care what they do in life; if they have a problem, they should either handle it or die(). I just want their statuses to be reaped automatically without my having to look at them. Luckily, Perl supports this by letting me put the following line in my program $SIG{CHLD} = 'IGNORE'; You can also use $SIG{CHLD} to install a handler if you are not as heartless as I am. This is similar to calling waitpid() in your main loop, but has the benefit of handling all children as soon as possible. The only drawback is that make the code harder to read and debug (since it is hard to predict exactly when the handler will run). use POSIX ":sys_wait_h"; my $handler = sub { my $pid; while (($pid = waitpid(-1, &WNOHANG)) > 0) { # do something with $pid } $SIG{CHLD} = $handler #reinstall the handler } $SIG{CHLD} = $handler; -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] <http://learn.perl.org/> <http://learn.perl.org/first-response>