in reply to forking and timeouts

In the else branch $pid is always zero, so in the signal handler you're trying to kill PID 0.

I don't think that makes sense (and if it does you should write a literal 0 to make things clearer).

Replies are listed 'Best First'.
Re^2: forking and timeouts
by Earindil (Beadle) on Aug 09, 2007 at 13:49 UTC
    Not sure I understand why it would always be 0. Wouldn't it only be 0 if it was the parent process, and an actual pid # if it's a child process?

      No it's the other way round. It will always be 0 in the child process, and the PID of the child process in the parent.

      To show it a bit clearer perhaps:

      $pid = fork(); if (!defined $pid) { print "Fork failed: $@"; } elsif ($pid) { print "I am the parent, my PID is $$ and my child's PID is $pid\n"; } else { print "I am the child, my PID is $$ and my parent's PID is " . getpp +id() . "\n"; }
        So based on the comments and more reading. This is what I came up with. Make more sense? The bolded parts are ones that I'm not sure I even need. Bits and pieces of this were pulled from other scripts I came across.
        foreach my $node (@nodes) {
                print "$node ";
                chomp $node;
                wait_for_a_kid() if keys %pid_to_node > 8;
                $pid = fork;
                if ($pid) {
                        ## parent does...
                        $pid_to_node{$pid} = $node;
                }
                else {
                        local $SIG {ALRM} = sub {
                        kill -15, $$ or die "kill: $!";
                        print "\tKilled PID $$\n"}; # Just SIGTERM.
                        eval {
                                ## child does...
                                setpgrp(0,0);
                                print $$."\n";
                                exit !&GetSvrStatus($node);
                                alarm 5;
                                waitpid $pid => 0;
                        };
                }
        }
        ## final reap:
        1 while wait_for_a_kid();