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

I'm trying to create a simple daemon process, ie, fork, exit the parent, and have the child inherited by the system to do its stuff.

I've tried this with the following code but running under cron doesn't seem to behave - I want it under cron to make make sure it restarts every hour in case it ever falls over.
my $pid = fork; if ( ! defined $pid ) { # fork failed throw_invalid "Couldn't fork"; } elsif ( $pid > 0 ) { # parent exit; } else { while ( 1 ) { sleep 1; # and do other snazzy stuff forever } }
$ ps -ef 

rbrown   29884  3162  0 11:58 ?        00:00:00 crond
rbrown   29885 29884  2 11:58 ?        00:00:03 solr-job-queue- <defunct>
rbrown   29886     1  2 11:58 ?        00:00:02 /usr/bin/perl -w /home/me/solr-job-queue-process.pl
Is it all because the parent can't die until it's child has, and that's why cron isn't clearing it from the process table?

Surely there's a way round this?

Any guidance greatly appreciated.

Replies are listed 'Best First'.
Re: daemon/fork: defunct parent not going away nicely
by dave_the_m (Monsignor) on Oct 14, 2011 at 11:28 UTC
    It'll be defunct because crond hasn't yet reaped the exited process. As to why it hasn't, I don't know; but I would speculate that crond is waiting for one for more of the STDIN/STDOUT/STDRR it passed to it's child to reach EOF; and maybe your child (crond's grandchild) is inheriting those file descriptors?

    Dave.

      I would speculate that crond is waiting for one for more of the STDIN/STDOUT/STDRR...

      That's right.  crond is generally attempting to read output from the jobs it started, which it would then typically try to mail somewhere.  (This is kind of like if you were to run your script using backticks from another Perl script (or the shell, unless it auto-reaps) — which would produce the exact same behavior of leaving a zombie behind.)

      As the (grand)child process inherits the standard file handles, they're not being closed when the parent part of your script exits, i.e. the child's duplicates remain open.

      The solution is to close those handles, or more properly, do as described in perlipc.

        thanks for the background and link.

        I remember this same issue years ago with a cgi-script used to start a daemon process, but kept the browser progress waiting, even tho the request had "finished".

        I just closed STDIN/OUT/ERR in the child before it does anything.
      Cheers Dave,

      That sounds very familiar now, needing to close then re-open filehandles, specifically stdin/out/err.
Re: daemon/fork: defunct parent not going away nicely
by Your Mother (Archbishop) on Oct 14, 2011 at 13:30 UTC
Re: daemon/fork: defunct parent not going away nicely
by Anonymous Monk on Oct 14, 2011 at 11:13 UTC
      Thanks, tho I'd rather understand why/what's going on with this one.