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

I can't find the proper solution to a perl problem...
In a perl program I am using exec to run a compiled binary. I need to run the binary over and over again. I have created a sub{} that performs the following:
 
  • opens a pipe
     
  • forks
     
  • The child process opens STDOUT on the pipe
     
  • The child process uses exec to run the binary
     
  • The parent process reads data from the pipe
     
  • both parent and child close their pipe handles

    This works fine except it leaves the binary process as a <defunct> zombie. This eventually takes away all the file handles and starts giving an error along the lines of "unable to fork"
    The manpage for ps says this:
    Processes marked <defunct> are dead processes (so-called "zombies") that remain because their parent has not destroyed them properly. These processes will be destroyed by init(8) if the parent process exits.

    What is the proper way to destroy a child process?
  • Replies are listed 'Best First'.
    Re: zombies after fork()
    by lhoward (Vicar) on May 29, 2000 at 07:52 UTC
      Probably the easiest and simplest way to handle prevent zombies is to install the IGNORE signal handler for SIGCHLD messages. Simply add the following line near the top of your program:
      $SIG{CHLD}='IGNORE';
      This assumes that your main program doesn't need to do anything when the children complete. If it does you will need a more complicated SIGCHLD handler. The following is a very standard SIGCHLD handler:
      $SIG{CHLD}=\&REAPER; sub REAPER{ my $stiff; while(($stiff = waitpid(-1,&WNOHANG))>0){ # do something with $stiff if you want } $SIG{CHLD}=\&REAPER; }
        Be careful when re-installing the signal handler. I was working on FreeBSD some time ago and had no end of trouble with my signal handlers until I stopped the re-install.

        Mik - with just a few words of warning.
        mikfire