[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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



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