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

Say I use a fork and create a child process...

I can wait for the child to terminate with wait...

How do I check whether the child has already terminated without having to wait for it? :-\ I'd like to keep on doing stuff, in case the child hasn't terminated yet :-|

Any ideas?

Replies are listed 'Best First'.
Re: Finding if a child process has terminated
by ikegami (Patriarch) on Mar 28, 2005 at 14:56 UTC

    From perlfunc:

    waitpid PID,FLAGS

    Waits for a particular child process to terminate and returns the pid of the deceased process, or -1 if there is no such child process. On some systems, a value of 0 indicates that there are processes still running. The status is returned in $?. If you say

    use POSIX ":sys_wait_h"; #... do { $kid = waitpid(-1, WNOHANG); } until $kid > 0;

    then you can do a non-blocking wait for all pending zombie processes. Non-blocking wait is available on machines supporting either the waitpid(2) or wait4(2) system calls. However, waiting for a particular pid with FLAGS of 0 is implemented everywhere. (Perl emulates the system call by remembering the status values of processes that have exited but have not been harvested by the Perl script yet.)

    Note that on some systems, a return value of -1 could mean that child processes are being automatically reaped. See the perlipc manpage for details, and for other examples.

    So

    if (waitpid($child_pid, WNOHANG) > 0) { ... the child just died ... }
Re: Finding if a child process has terminated
by Joost (Canon) on Mar 28, 2005 at 14:44 UTC
Re: Finding if a child process has terminated
by Limbic~Region (Chancellor) on Mar 28, 2005 at 14:43 UTC
    cog,
    I am not sure what you are asking for. Are you looking for a non-blocking wait or are you looking for a way to just detect when the child process ends? If the former, look at perldoc -f waitpid, if the latter, look at adding a SIG handler.

    Cheers - L~R

Re: Finding if a child process has terminated
by ambrus (Abbot) on Mar 28, 2005 at 14:56 UTC
    You can use the waitpid function with the WNOHANG flag in its last argument (its value is 1) for this.
Re: Finding if a child process has terminated
by Fletch (Bishop) on Mar 28, 2005 at 14:57 UTC

    Use kill 0 => $childpid to check; if that returns false and $! == ERSCH then it's not running.

      Note that I have to add a
      $SIG{CHLD}='IGNORE';
      for this to work (with no other previous $SIG{CHLD})

      Running AIX 5.2 Perl 5.8.0
      --------------
      "But what of all those sweet words you spoke in private?"
      "Oh that's just what we call pillow talk, baby, that's all."

        Ah, you're correct. Until something waits on the process it'll still have an entry in the process table and hence be "alive" as far as sending signal 0 goes. Sending signal 0 is probably of more use in checking if an unrelated process (or at least non-descendent process) is alive.

        Update: And you can see this behavior with the code below.