umitd has asked for the wisdom of the Perl Monks concerning the following question:
I have a perl program which forks children and does some processing depending on how each child exits. I keep the exited child's pid and return code in a hash to process later:
$SIG{CHLD} = \&waitforchildren; # reaper: sub waitforchildren { my $cpid; while ( ($cpid = waitpid(-1, &WNOHANG)) > 0 ) { $TrappedPIDs{$cpid} = WEXITSTATUS($?) if WIFEXITED($?); } } # processing routine ... foreach $pid ( keys(%TrappedPIDs) ) { # check return code for pid and do something }
My program can only trap some of the children exited. Some others exit, but never detected by my foreach loop. So my program thinks that they are still running. So I modified the reaper routine to print all trapped PIDs of exited children:
sub waitforchildren { my $cpid; my $pidlist = " "; + while ( ($cpid = waitpid(-1, &WNOHANG)) > 0 ) { $TrappedPIDs{$cpid} = WEXITSTATUS($?) if WIFEXITED($?); } foreach $cpid ( keys(%TrappedPIDs) ) { + $pidlist .= " ".$cpid; } print " TRAPPED PIDS: $pidlist \n"; }
This printed the following:
TRAPPED PIDS: 20090 19934
TRAPPED PIDS: 20090 19934 16465
TRAPPED PIDS: 20090 19934 20091 16465
TRAPPED PIDS: 20092
I also added a print command to my processing routine. It only checks 20092! So it seems that hash %TrappedPIDs ended up having just one PID despite the fact that the reaper routine caught more PIDs and added them to the hash! I understand that reaper routine itself can be interrupted with the signals of children which died around the same time. However, this should not destroy the elements of the hash. What am I doing wrong here?
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: hash elements are lost during reaping
by Anonymous Monk on Dec 11, 2012 at 11:10 UTC | |
by umitd (Initiate) on Dec 11, 2012 at 11:30 UTC | |
by roboticus (Chancellor) on Dec 11, 2012 at 11:41 UTC |