kage-yojimbo has asked for the wisdom of the Perl Monks concerning the following question:

Good Morning Monks! I am writing a WIN32 communication tester which forks so that a large number of paths can be tested. I am having problems getting the process to wait until EVERY child has finished running. ( Some of these paths have comm troubles so the tracert or ping commands will take longer to complete. )
I have tried using the WAIT, but that seems to just look for one child. Here's my code - any suggestions?
Thank you!
-- kage-yojimbo
# extract IP address and site name from input file foreach my $line (<>) { # grab the data of interest - that would be an IP address @words = match_array ( $line, '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' +, '\s+' ); if ($#words) { # grab the ip address and name from each line of input $ip = $words[0]; $name = "@words[1..$#words]"; # push that information onto the test stack push @test_stack, $ip; push @test_stack, $name; } } # foreach my $line (<>) # do a traceroute if ($traceroute_flag) { $header = "\nPerforming traceroute to "; $command = "tracert"; } # do a ping if ($ping_flag) { $header = "\nSending test ping to "; $command = "ping -l 1200 "; } # fork to do everything at once # go through the list of ip addresses and fork to do commands on each +address for (my $i = 0; $i < $#test_stack; $i+=2) { my $ip = $test_stack[$i]; my $name = $test_stack[$i+1]; my $pid; # process id of spawned process # print ("forked for ip = $ip, name = $name \n"); next if $pid = fork; # parent goes to next command pair die "fork failed: $!" unless defined $pid; system ( " $command $ip > logs\\$ip.log " ); exit; # end the child process } #print "All forked processes dispatched !\n"; #print "Wait for all forked processes to finish\n"; 1 while wait() > 0; #print "Wait a little longer for processes to finish\n"; sleep 5;

Replies are listed 'Best First'.
Re: wait problem for WIN32 perl
by thundergnat (Deacon) on May 19, 2005 at 17:33 UTC

    You don't seem to be saving the child pids anywhere so you can check to see if they have completed.

    Why don't you take a look at Randal Schwartz's May 2002 Unix Review column. It has an example of doing exactly this.

    Doing many things, like pings

      Thanks for the suggestion. After much reading and analysis of the sample code I discovered that my WIN2000 servers are returning PIDs which are negative numbers. That threw a kink into processing which was designed to look for the "no more processes" flag.

        The negative pids aren't produced by win2k, but by Perl's fork emulation on win32 which uses -$tid as the (pseudo-) process id.

        This behaviour is documented in perlfork and if you page down to the bugs section, you'll see that the problem you encountered with wait is obliquely described there.

        It makes the correct way to wait for all subprocesses to terminate:

        1 while wait() != -1;

        This relies on the fact that the first thread of a process is 1, which means that no forked pseudo-process will have pid of -1 and should therefore work cross-platform.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
        "Science is about questioning the status quo. Questioning authority".
        The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.