use POSIX ":sys_wait_h"; ... #------------------------------------------------------------------------------------------------------------- #------------------------------------------------------------------------------------------------------------- sub S_TestForking2 { my ($lSleepTime); my ($lProcessLabel, @lPidArray); my $lFinished = 0; my $lStillRunning = 0; my $isAlive; my $kid; my $lpid; my $i; my %lRunningPidHash = (); my @lCmdArray; my $lCmdIndex; # Create a bunch of fake commands that take time push (@lCmdArray, "sleep 20"); push (@lCmdArray, "sleep 25"); push (@lCmdArray, "sleep 38"); push (@lCmdArray, "sleep 20"); push (@lCmdArray, "sleep 17"); push (@lCmdArray, "sleep 15"); push (@lCmdArray, "sleep 25"); push (@lCmdArray, "sleep 30"); push (@lCmdArray, "sleep 15"); $lFinished = 0; while ($lFinished == 0) { # Count the running processes using the pid array we filled when we forked the child $lStillRunning = 0; foreach $lpid (sort keys %lRunningPidHash) { waitpid($lpid, WNOHANG); if ( $? == -1 ) { $lStillRunning++; } elsif ($? == 0) { # If we ask about this id again we get -1 forever delete $lRunningPidHash{$lpid}; } print "\t$lpid = $?\n"; } print "Running processes: $lStillRunning\n"; # If our command array is zero and our running processes is zero - we can just exit if ( $lStillRunning == 0 and scalar (@lCmdArray) == 0 ) { $lFinished = 1; last; } # Pop the commands off the command array so we always have 6 processes running for ($i = $lStillRunning; $i < 3; $i++) { my $lCmd = pop (@lCmdArray); if ( $lCmd ) { $lpid = fork; die "Couldn't fork: $!" unless defined $lpid; if ( $lpid ) { # parent print "Forked off a child: $lCmd - $lpid\n"; $lRunningPidHash{$lpid} = 1; } else { # child close (STDIN); close (STDOUT); close (STDERR); exec ($lCmd) or die ("Error: could not exec command : $lCmd : $!\n"); } } } # Sleep a few seconds and re scan sleep (5); } print "Parent exiting\n"; } # S_TestForking2