Be sure and wait against your sub processes. When they’re done, that will
ensure they clear. Disclaimer: I cut
this out of something I wrote and cleaned it up for consumption so I may have
missed something here and there in the cleanup. Something like this: foreach $Something ($Somelist) { if (scalar(keys %PidList)
< $Parms{MaxThreads}) { print "Creating
a thread for $Something\n”; if ($ForkResult=fork) { print
"Adding $ForkResult to thread tracking list\n"; #Keep the PID to track $PidList{$ForkResult}=$Something; } elsif
(defined $ForkResult) { #We're
the child print
"Childthread: Thread is executing a process $Something\n"; &Process; -----àcall some subroutine you want to do. exit; }else { &Mainlog ("Unknown error forking: $!
$^E","FATAL"); } } else { print "Maximum copy operations in progress ($Parms{MaxThreads}) - waiting 5
seconds for some to complete\n"; #
We have the maximum number of processes executing -
wait for interval then try again. sleep 5; #
Wait against the children &WaitCopies; #Look
again to see if we can start more copies redo Begin; } } print "No more pending copy operations
queued - waiting for completion of operations in progress\n"; # Wait on all the executing processes while (scalar (keys %PidList)
!= 0 )
{ print "Waiting for copies to complete:
",scalar (keys %PidList)," in progress\n"; sleep 5;
&WaitCopies;
} # We’re done sub WaitCopies { foreach $Process (keys %PidList) { $Result = waitpid( $Process,
&POSIX::WNOHANG ); if
($Result==-1) {
$Result = waitpid( $Process, &POSIX::WNOHANG );
print "Process $Process ($PidList{$Process}) complete\n";
delete $PidList{$Process}; } else
{
print
"Process $Process ($PidList{$Process}) still
active\n";
} } } -----Original Message----- Hi all, I'd really
appreciate any help with a problem I am having. I am trying to
achieve the following basic logic in Perl on W2k Server... ·
When it starts,
my script spawns a pre-defined number (10) of identical sub-processes ·
It then
continuously loops back every few seconds to check if any have completed ·
If a processes
has completed, it spawns another instance to replace it ·
And so on I have tried using
Win32::Process and that works well, but when the script terminates the
sub-processes continue to run (detatched). Reading the
documentation it seems to me that Win32:Job is more suitable my rough attempt
at coding (below) is even worse that the version using Win32::Process - it does
what is described above using the "watch" method to keep an eye on
the spawned processes and starting new ones as required. But the problem is,
when the last of the 10 originally spawned processes exits, the entire script
exits and all the sub-processes die with it rather than continuing to spawning
new processes until I decide for some arbitrary reason to exit and kill the
entire process tree. Has anybody got any
pointers as to how I can add new processes to a Win32::Job structure and have
them included in the "watch" method? Thanks. Barry Caruth. --- code starts here --- use strict; use warnings; use Win32::Job; # Use sleep.exe from resource kit to hide complexity of real process our $exe_path = "c:\\program files\\resource kit\\sleep.exe"; our $count = 0; my $return = 0; our %pid_hash = (); our $job = Win32::Job->new or die $!; while( $count < 10 ) # Max number of threads { &start_process; $count++; }; while ($return == 0) { sleep 2; $return =
$job->watch(\&handler,2,1); }; print "done\n"; sub start_process { my $pid; $pid = $job->spawn( $exe_path,
"sleep " . (5 * ($count+1))) or die $!; $pid_hash{$pid} = ""; print "Process $pid
Started\n"; }; sub handler { my $status; my $pid; my $value; my $exitcode = 0; $status = $job->status(); foreach $pid (keys %$status) {
$exitcode = $$status{$pid}{exitcode}; if ($exitcode
!= 259) {
if (exists $pid_hash{$pid}) {
print "Process $pid Finished : $exitcode\n";
delete $pid_hash{$pid};
&start_process;
}; }; }; return 0; }; |