in reply to How do you wait for a process to end ?

You're only waiting for one process to end, then removing ten entries in your array of pids. The waitpid call will return status for only one deceased process, but you clear your array of ten pids in response. (BTW, it's clearer to write @pids = () instead of $#pids = -1.)

Another way to structure this would be to set up a signal handler for SIGCHLD and issue a wait there. Something like this (untested):

sub reapchild { # already using POSIX, right?? 0 while waitpid(-1, &WNOHANG) > 0; } $SIG{CHLD} = \&reapchild;

HTH

Replies are listed 'Best First'.
Re: Re: How do you wait for a process to end ?
by jalebie (Acolyte) on Aug 23, 2001 at 19:03 UTC
    Thanks man, I thought that the -1 in the waitpid call would wait for "all" child processes to end. Now its clearer why this is happening. I understand connecting the reaper subroutine to the child , but how would I make it so that I would know that exactly 10 processes have ended ??

    p.s I have never used signal handlers before
    Waris

      No, the -1 says "any" process, not "all processes". Usually you use waitpid to wait for a specific pid (hence the name ;-). But in both cases, it will return upon detecting one terminated child process.

      To create a throttle in the signal handler, you need to make the parent stop when your list of pids reaches ten elements (like you're doing). Then you need to make the signal handler routine (reapchild in the example above) shorten the list every time waitpid returns something other than -1. So:

      sub reapchild { while (waitpid(-1, &WNOHANG) > 0) { pop @pids; } }
      This is quick-and-dirty in that your array of pids may not correspond to what's really out there. It would be better to take the returned pid from waitpid and delete that particular element from the array. TIMTOWTDI, but here's a simple one:
      sub reapchild { my ($pid, $index); PID: while (($pid = waitpid(-1, &WNOHANG)) > 0) { foreach my $i (0..$#pids) { if ($pids[$i] == $pid) { splice @pids, $i, 1; next PID; } } warn "Unexpected $pid returned!\n"; } }

      HTH

      You can just keep a running count of your current children - increment on each successful fork, and decrement on a successful call to \&reaper.