in reply to Waiting For Multiple Programs to Complete

The wait function returns the pid of a completed child process. If you keep a hash with pid as key and whatever identifying data you like as value, you can tell which subtask has finished.

After Compline,
Zaxo

  • Comment on Re: Waiting For Multiple Programs to Complete

Replies are listed 'Best First'.
Re^2: Waiting For Multiple Programs to Complete
by NathanE (Beadle) on Oct 07, 2005 at 22:08 UTC
    The problem with this is that I can only run one program at a time (as wait literally waits before doing anything else) when I need to complete parallel tasks and react to task completion etc. I don't think wait can do this, but I may be wrong?

    My other option is to create an independant hash table and provide each program a unique ID that it uses to store its status in the hash table. Then, I can just cycle over this hash key waiting for a change of status to what I'm looking for and continuing.. BUT - I'd rather find a more native way to do it..

    Also, if I were to do it that way, does anyone know the most efficient way to keep checking for this hash change? I don't want to loop over it constantly as that would probably consume too much CPU.. Maybe set a sleep time within a loop - anyone have experience with anything along these lines?

    Thanks again everyone.

      The wait call is a form of sleep. It sleeps until SIGCHLD if there are no completed children queued up for attention. If there are, it returns the pid of the one it serviced.

      Your application might look like this skeleton,

      our %kid; sub forkus { my $task = shift; # it's a hash ref defined(my $cpid = fork) or warn $! and return; $kid{$cpid} = $_->id, return $cpid if $cpid; exec $_->cmd; exit -1; } forkus($_) for (@first_tasks); while (%kid) { my $cpid = wait; # sleep until somebody's done forkus(next_task($cpid)) if more($cpid); # suitably defined delete $kid{$cpid}; }
      I've glossed over the design of the task hashes and the next_task() and more() functions. They will be application dependent.

      POE may be just what you need, but I find it somewhat difficult to work with. Lack of practice, perhaps.

      After Compline,
      Zaxo

      Try:
      use POSIX ":sys_wait_h"; waitpid(-1,WNOHANG);
      to check for any waiting processes, and return immediately instead of blocking if there aren't any.

      Or, use a handler for $SIG{CHLD} to do your thing, and handle processes exiting as they come in.