Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses

hash elements are lost during reaping

by umitd (Initiate)
on Dec 11, 2012 at 10:42 UTC ( #1008261=perlquestion: print w/replies, xml ) Need Help??
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

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

    What am I doing wrong here?

    You're assuming its the same hash , print out the reference and you'll see that its different,  warn \%TrappedPIDs;

    But I'm guessing as you don't show the forking part

    :)Mr. Peabody Explains fork()

      Thanks for the reply. My fork routine saves pids of children in another hash to be compared in the processing routine:

      sub StartJob { my $pid; my $sid = shift; FORK: { if ($pid = fork) { # # This is the dispatcher! # $JobPIDs{$pid} = $sid; # add pid, sid pair to th +e hash } elsif ($pid == 0) { ....

      The processing routine goes like this:

      foreach $pid ( keys(%TrappedPIDs) ) { $rc = $TrappedPIDs{$pid}; print " CHECKING: trapped pid: $pid RC: $rc \n"; if ( exists($JobPIDs{$pid}) and $rc == 0 ) { # do the processing .. }
      %TrappedPIDs is a global hash. How come it can be different?


        How come it can be different?

        With you showing only small code fragments, it's rather hard to say. It's kind of like the old joke:

        Goofus is searching for his diamond ring under a streetlamp.

        Gallant comes to help, and after about 15 minutes, he says "Hey--about where were you standing when you lost the ring?".

        Goofus: "Over there in the parking lot."

        Gallant (surprised): "Well, then why are you looking over here?"

        Goofus: "The light is better."


        When your only tool is a hammer, all problems look like your thumb.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1008261]
Approved by Ratazong
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (2)
As of 2018-01-21 01:24 GMT
Find Nodes?
    Voting Booth?
    How did you see in the new year?

    Results (227 votes). Check out past polls.