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

Hello! I am trying to write a preforking server and have got a copy of exactly what I need from the Perl cookbook (Chapter 17). After a few teething problems where the server kept forking more and more children (I checked the result of wait in REAPER being greater than -1 before decrementing the number of children left)
sub REAPER { # takes care of dead children $SIG{CHLD} = \&REAPER; my $pid = wait; if ($pid > -1) { $children --; print "child $pid died, only $children left\n"; delete $children{$pid}; } else { $children = 0; } }
This appears to work, except that the master process does not appear to be being woken up from its sleep when a child dies:
# And maintain the population. while (1) { sleep; # wait for a signal (i.e., child's death) print "got woken up by signal\n"; for ($i = $children; $i < $PREFORK; $i++) { make_new_child(); # top up the child pool } }
The master process only appears to be woken up when the last of the children dies - resulting in the master spawning all the children at once - not what I was after. Interestingly, I've copied the script to a Mandrake 9 machine, and found that the sleep is interrupted at the point a child dies. However, I found a different problem there in that my client script fell over with IO::Socket::INET: connect: Cannot assign requested address So, is there a problem with signals on HPUX or is the example given a bit naive? Many thanks

Replies are listed 'Best First'.
Re: 100 years sleep on HPUX
by tilly (Archbishop) on Feb 21, 2004 at 02:03 UTC
    It is possible that a wait can return -1 not when there are no children, but when things are being autoreaped. Also note that as noted in perlipc, you cannot rely on signal handlers being re-entrant. Setting a signal handler inside of a signal handler will not work on many platforms.

    My sincere advice is to avoid playing with signal handlers for this. Just pull out Parallel::ForkManager to keep a fixed number of children alive. Alternately never sleep. Just use wait to block until a child exits, and then proceed.