in reply to Re: Process Management
in thread Process Management

Although not directly related to the OP's question, this is still important.

There's a subtle bug in this code that I have seen repeatedly. This code assumes two potential returns from fork. The fork call actually has three potential return values, not two.

I learned about this when a long-running process started failing when it was moved to a much, much faster machine. It forked enough child processes in a burst to run out of process slots and then failed. Since the return was not true, it went on to do work as a child and exited when it was done. Now, the main process was gone.

Update: As almut pointed out, the undef case was dealt with in the else. I can only say that I'm a little oversensitive to this bug after losing a fair amount of time on the above case.
G. Wade

Replies are listed 'Best First'.
Re^3: Process Management
by almut (Canon) on Jan 18, 2009 at 13:53 UTC
    There's a subtle bug...

    Isn't doom already taking care of the 'fork() failed' case (returning undef) with this line?

    ... } else { # this is child code die "cannot fork: $!" unless defined $pid; # <-- ...

      Drat! I missed that.

      G. Wade
Re^3: Process Management
by doom (Deacon) on Jan 18, 2009 at 09:03 UTC
    That's interesting. So is your point that this is a case where one should check if the return is defined (and not just "true"), or does there need to be a third branch to handle the "0"?

    Neither the examples in perlipc or in the Perl Cookbook make any attempt at special handling of a return of "0".

      My point is that there are actually three cases that need to be dealt with. Since fork almost never fails, people often forget the undef case and just handle true as parent and false as child.

      I like handling them as three separate cases, because the parent may be able to recover.

      In any case where the parent continues, handling the undef is important. Otherwise, you end up with a subtle, hard to reproduce bug.

      G. Wade