[Omaha.pm] Perl, fork, and waitpid()

Jay Hannah jay at jays.net
Tue Apr 21 05:57:21 PDT 2009


On Apr 20, 2009, at 9:16 PM, George Neill wrote:
> cat test.input | xargs --max-procs=4 --replace=timeout perl -e 'print
> "starting timeout\n"; sleep(timeout); print "finished timeout\n";'

Oh, neat! I had no idea xargs did that. I use xargs all the time, but  
hadn't seen --max-procs before. Thanks!  :)

On Apr 20, 2009, at 10:38 PM, Dan Linder wrote:
> Thanks for the pointers to POE and xargs.  Unfortunately I'm  
> restricted to using Perl core modules (and probably back to Perl  
> 5.001 from 1995).

How so? root is handy, but you don't need root to build you own perl  
+ POE (or anything CPAN). You can do it all in your home directory if  
root isn't playing ball.

On Apr 20, 2009, at 11:00 PM, George Neill wrote:
> Do you know the POE internals?
>
> # Detect the CHLD signal as each of our children exits.
>
> sub sig_child {
>     my ( $heap, $sig, $pid, $exit_val ) = @_[ HEAP, ARG0, ARG1,  
> ARG2 ];
>     my $details = delete $heap->{$pid};
>     # warn "$$: Child $pid exited";
> }
>
> ... got me thinking about the back-end.  I am guessing POE might give
> some weird results on the old sysV signal implementations as SIGCHLD
> has different semantics there.

I am not versed in POE internals.

 From a users perspective, everything is driven by POE::Kernel  
sig_child():

http://search.cpan.org/~rcaputo/POE-1.005/lib/POE/ 
Kernel.pm#sig_child_PROCESS_ID_[,_EVENT_NAME]

Internally it appears POE::Resource::Signals is the place where  
waitpid() is called in two different places:


sub _data_sig_handle_poll_event {
   ...
   # Reap children for as long as waitpid(2) says something
   # interesting has happened.
   my $pid;
   while ($pid = waitpid(-1, WNOHANG)) {
     # waitpid(2) returned a process ID.  Emit an appropriate SIGCHLD
     # event and loop around again.

     if ((RUNNING_IN_HELL and $pid < -1) or ($pid > 0)) {
       if (RUNNING_IN_HELL or WIFEXITED($?) or WIFSIGNALED($?)) {

         if (TRACE_SIGNALS) {
           _warn("<sg> POE::Kernel detected SIGCHLD (pid=$pid; exit= 
$?)");
         }
         ...


### End-run leak checking.
sub _data_sig_finalize {
   ...
   unless (RUNNING_IN_HELL) {
     local $!;
     local $?;
     until ((my $pid = waitpid( -1, 0 )) == -1) {
       _warn( "!!! Child process PID:$pid reaped: $!\n" ) if $pid;
       $finalized_ok = 0;
     }
   }


I see no mention anywhere in the tarball of "sys v" or "sysv" (case  
insensitive).

j




More information about the Omaha-pm mailing list