http://qs1969.pair.com?node_id=145512

c has asked for the wisdom of the Perl Monks concerning the following question:

i wrote this a short while back as i started down the path of trying to understand wait. i think i've got a pretty good handle on how it works, and the idea that you really need to wait for each child process, or at least until they all close. in a response to my previous post, bluto offers a suggestion on how to handle the problem by incrementing a variable for each child process spawned and then waiting in a while loop as the variable is decremented. That makes sense to me, or at least the "how it works" makes sense.
I found this code, which seems to work as well, and really does not let the parent pid exit until all children are through as evidenced by the command line not returning until all children run through. however i'm not really certain just *how* it works

## wait on chid processes to exit while (wait() != -1) { return 1 if ($?); }

i see that return will return a value of 1 if there is a child process error held in $?, however the condition of the while is what confuses me. wait not equal to -1. so in one line its waiting, but checking on a value, and i am not sure where the value is coming from.

mad thanks! -c

Replies are listed 'Best First'.
Re: what is this doing? - while (wait() != -1)
by Zaxo (Archbishop) on Feb 14, 2002 at 18:07 UTC

    wait evaluates to the pid of a child as it exits, effectively sleeping till then. If there are no children, wait returns -1, so the while loop is testing whether any more remain.

    Is this code in a sub which is called again after a child error is handled?

    After Compline,
    Zaxo

Re: what is this doing? - while (wait() != -1)
by lestrrat (Deacon) on Feb 14, 2002 at 18:08 UTC

    wait/waitpid returns -1 when there are no children or the children are automatically being reaped ( according to perldoc -f wait ). So the loop is waiting for all of the children to exit

    I personally don't like this child count decrementing business... I'd rather explicitly check if the pid that I just got is the pid that I'm waiting for, i.e., my child. That may just be me...

    ## XXX - I use hashes in this type of situation ## because I usually associate more meta data to a pid ## which must be used by the parent when the child ## exits... and delete $hash{ $foo } is cleaner ## than splice() to me :) use POSIX; my %pids; for( 1 .. $numchild ) { my $pid = fork(); ## check if $pid id defined, etc. if( $pid ) { ## parent $pids{ $pid } = 1; } else { do_interesting_stuff(); exit; } } while( ( my $pid = waitpid(-1, POSIX::WNOHANG() ) ) > 0 ){ if( exists $pids{ $pid } ) { delete $pids{ $pid }; } else { print STDERR "Unknown child $pid\n"; } }
Re: what is this doing? - while (wait() != -1)
by dragonchild (Archbishop) on Feb 14, 2002 at 18:02 UTC
    It's the return value from wait(). :-)

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.