in reply to waitpid(-1, WNOHANG) is hanging

Incidentally, the script terminates after the third child exits without waiting for the sleep to complete.

If you have a signal handler set up, sleep (and many other system calls) will get interrupted by signals (returning error EINTR). This is a good thing, as it allows your signal handler to be called.

sub uninterruptible_sleep { my ($dur) = @_; my $until = time() + $dur; while (1) { $dur = $until - time(); last if $dur <= 0; sleep($dur); } return 1; }