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

I have a daemon running that executes multiple children at any given minute. That part work great. The problem that I have is that when the children exit they turn into zombies. I need to have the daemon act like a cron scheduler executing one or more children every minute, not waiting on the children to exit, which could take up to 10-15 minutes. What I need is to have the parent sitting waiting for the top of the minute where it sets in motion children who continue on their own. Then the parent returns to waiting for the top of the minute. Ideas?

Replies are listed 'Best First'.
Re: Multiple Childern/Zombies
by ikegami (Patriarch) on Apr 19, 2011 at 21:40 UTC
    If you don't care to collect the exit values of the child,
    $SIG{CHLD} = 'IGNORE';
      Thank you all. I ended up using $SIG(CHLD) = 'IGNORE'; I didn't care about the response from the "Grandchildren" because they have their own error handling and logging. Thanks again.
Re: Multiple Childern/Zombies
by Eliya (Vicar) on Apr 19, 2011 at 21:12 UTC

    The OS will notify the parent of a child's death by sending it a SIGCHLD signal, so you can set up a signal handler in which you reap the children using wait or waitpid.  In its most simple case:

    $SIG{CHLD} = sub { wait };

    (On many systems, $SIG{CHLD} = 'IGNORE'; has the same effect.)

Re: Multiple Childern/Zombies
by bart (Canon) on Apr 19, 2011 at 20:54 UTC
    If you fork before launching the (grand)children and then exit in the child (the parent is the daemon), the zombies should go away.
Re: Multiple Childern/Zombies
by Argel (Prior) on Apr 19, 2011 at 22:39 UTC
    Maybe you are not creating a proper daemon. The following may help:
    use IO::Socket; use POSIX qw(WNOHANG setsid); sub daemonize { $SIG{CHLD} = 'IGNORE'; # Configure to autoreap zombies die "Can't fork" unless defined ( my $child = fork ); # FORK +<<<<<<<<<<<< CORE::exit(0) if $child; # Parent exits setsid(); # Become session leader open( STDIN, "</dev/null" ); # Detach STDIN from shell open( STDOUT, ">/dev/null" ); # Detach STDOUT from shell open( STDERR, ">&STDOUT" ); # Detach STDERR from shell chdir '/tmp'; # Change working directory umask(0); # Reset umask $ENV{PATH} = '/bin:/sbin:/usr/sbin'; # Reset PATH }
    See Re: Persistent perl for more.

    Elda Taluta; Sarks Sark; Ark Arks