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

Proc::Fork is attractive for forking processes. I like how each aspect of the fork has a discrete and explicit code block.

The one thing I like more about Parallel::ForkManager is $pm->wait_all_children; - the ability to wait on all the children via a single method call.

The Proc::Fork docs show a call to waitpid but it is not clear how to wait on all children, ignoring those who have died. How would such a function be written? UPDATE The important variation on wait_all_children for my purposes is non-blocking wait: if one of the children dies, then that is perfectly fine. But we wait on those that have not died until they finish.

Replies are listed 'Best First'.
Re: wait_all_children for Proc::Fork?
by ikegami (Patriarch) on Jun 09, 2009 at 16:17 UTC

    The important variation on wait_all_children for my purposes is non-blocking wait

    Then you have to poll (like Parallel::ForkManager) or use a signal handler.

Re: wait_all_children for Proc::Fork?
by repellent (Priest) on Jun 09, 2009 at 17:41 UTC
    I would imagine collecting all the child PIDs in the parent process first and then waitpid for them in a loop:
    parent { push @child_pids, $_[0] }

    and then after the last run_fork:
    # wait to reap all children for my $pid (@child_pids) { waitpid $pid, 0; }
      At the risk of identifying a problem without proposing a solution, the above would work until one of the children hangs - causing the parent to hang.

      A user level that continues to overstate my experience :-))
        Right. Fix the real problem in the child, or just add a timeout:
        # wait to reap all children for my $pid (@child_pids) { local $SIG{__DIE__}; local $@ = ""; eval { local $SIG{ALRM} = sub { die("alarm\n") }; alarm(3600); # potentially long operation waitpid $pid, 0; alarm(0); 1; } or do { die($@) unless $@ eq "alarm\n"; # timed out warn("Waited too long for child $pid. Skipping it.\n"); } }