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

Hi,
I'm running a test on a Unix box (AIX 4.3). I have a process that will fork to call other processes on Unix, and I'm using waitpid to determine when the children are finished, but I'm concerned that I might run into problems.

The scenario is that I call fork several times, and inside each child process I use 'system' to call another process. I think my children are automatically reaped, so my concern is this: Is is possible that another process could be launched on Unix that could pick up the PID of one of my dead children, before I know that the child is dead?

Thanks...

20040913 Edit by ysth: change title from 'waitpid'

Replies are listed 'Best First'.
Re: Possible waitpid problem - pid reuse?
by Zaxo (Archbishop) on Sep 13, 2004 at 01:17 UTC

    The exited child processes will hang around in Z[ombie] state until wait or waitpid collects their exit status. That means their pid is still in use until you release it.

    The exception occurs when you have a $SIG{CHLD} handler. That makes the system think you've handled it already. On some systems you can make nobody care what happens to the kids by setting the handler to 'IGNORE', but that's clearly not your situation.

    After Compline,
    Zaxo

      > The exception occurs when you have a $SIG{CHLD} handler. That makes the system think you've handled it already.

      Not true. The program below forks, the child exits immediately. You will see that the signal handler is fired, but the child process stays around (as a zombie) until it's reaped by the waitpid call.

      $SIG{CHLD} = sub {print("SIGCHLD\n")}; exit unless $pid = fork; sleep 1; system "ps -p $pid"; waitpid $pid, 0; system "ps -p $pid"; __END__ SIGCHLD PID TTY TIME CMD 29260 pts/32 00:00:00 perl <defunct> SIGCHLD PID TTY TIME CMD SIGCHLD
      The signal handler fires three times in total: one for the child process, and once each for the calls to system.

      It's only when you explicitely set $SIG{CHLD} to IGNORE that child processes stay behind.

      It's noteworthy to remember that POSIX does not specify what should happen if $SIG{CHLD} is ignored. (Which makes it a joy to program platform independently on Unix)

Re: Possible waitpid problem - pid reuse?
by borisz (Canon) on Sep 13, 2004 at 00:12 UTC
    You mean another unrelated process reuse the pid of your dead child before the parent knows? Thats not possible on Unix ( but I know nothing about AIX ).
    Boris
Re: Possible waitpid problem - pid reuse?
by graff (Chancellor) on Sep 13, 2004 at 00:36 UTC
    Have you thought about using "exec()" instead of "system()" to start whatever process is being run by the child? If the child is doing some setup stuff, running some single command line and exiting, then passing that command line to "exec()" will cause the the child process to be replaced by the exec'ed command. This means that the child's PID gets "taken over" by the exec'ed process, which also means that the PID returned to the parent by "fork" is the only one you need to worry about.

    Of course, if anything needs to be done in the child after its sub-process finishes but before the child exits, then you wouldn't want to use "exec()" -- any code located after an "exec()" call is never reached (exec does not return to the caller).

      Given that system does a fork, exec and then blocks until the called process completes I don't see what benefit a stright exec would give.

      cheers

      tachyon