Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Limiting the number of forks in a foreach loop 1

Status
Not open for further replies.
Jun 19, 2001
86
US
The following code creates a new fork evertime the loop executes. The number of loops depends on the number of elements in @queue array. I don't want to spawn more than 3 forks at any given time. I need to wait somehow. For some reason I'm having a mental block on how to do this. It's like contemplating the edge of the universe. Any help would be greatly appreciated!

Nathan

#run subroutine depending on schedule type
foreach $queue (@queue){
if (defined($pid = fork)){
if ($pid) {
print "Parent: forked child ($pid)\n";
} else {
#execute schedule scripts
($queue_id, $schedule_id)=split(/\|/, $queue);
if ($schedule_id == 0){system("immediate.pl $queue_id");}
elsif ($schedule_id == 1){system("hourly.pl $queue_id");}
elsif ($schedule_id == 2){system("daily.pl $queue_id");}
elsif ($schedule_id == 3){system("weekly.pl $queue_id");}
elsif ($schedule_id == 4){system("monthly.pl $queue_id");}
elsif ($schedule_id == 5){system("yearly.pl $queue_id");}
else {print "Oops I did it again";}
last;
}
}
}
 
[tt]wait()[/tt] will wait for a child process to terminate and return the pid of the process that ended. So something like:

[tt]$children = 0;
foreach $queue (@queue) {
if ($children == 3) {
$pid = wait();
$children--;
}

if (defined($pid = fork)) {
if ($pid) {
$children++;
} else {
# ...
}
}
}
[/tt]
 
rosenk,

That works but with an exepected result. It creates three processes as expected. The unexpected is that it waits for the first three processes to finish before starting three more. I was thinking that as each process dies it would start another.

Here is the output:
Parent: forked child number 1 (-1016)!
Parent: forked child number 2 (-796)!
Parent: forked child number 3 (-976)!
Parent: forked child number 3 (-584)!
Parent: forked child number 3 (-1016)!
Parent: forked child number 3 (-816)!

Not sure why child number 3 shows up four times. I suspect it's because we aren't resetting $children to 0.

Nathan
 
I was wrong in the previous post. It works exactly as it should. Thanks for your help!

Nathan
 
Tom, [tt]wait()[/tt] should return if the process terminates for any reason, including external signals. There would be a problem, though, if there was a child process that never terminated
 
Hi all

this command

$pid = wait();

It's my understanding that this will wait for *all* child processes, did I get that wrong? Mike

Want to get great answers to your Tek-Tips questions? Have a look at faq219-2884

It's like this; even samurai have teddy bears, and even teddy bears get drunk.
 
It will wait for any child process to terminate and return the PID of that child process. If there are several that have already terminated prior to calling [tt]wait()[/tt], it will immediately return the PID of one of those children, no telling which.

It will return -1 if you do not have any child processes.
 
Aha :)

Seems to wait for the exit of the *last* child you started.

I tried this script both ways, if you start the 15 second child last it will wait for that one.

SunOS 5.8 & Perl 5.6.1

use strict;
use warnings;

unless( fork() ){
# child process
sleep 15;
}

unless( fork() ){
# child process
sleep 10;
}

unless( fork() ){
# child process
sleep 5;
}

wait();
Mike

Want to get great answers to your Tek-Tips questions? Have a look at faq219-2884

It's like this; even samurai have teddy bears, and even teddy bears get drunk.
 
To Mike and Nathan,

the child process must exit() after it is finished, otherwise it continues to execute the rest of the script. Putting [tt]exit();[/tt] as the last statement of the child's else block (or the unless block in Mike's case) will accomplish this.

In Nathan's case if the child doesn't exit, it will continue to the next value of the for loop queue with it's own private copy of the for loop state when it was forked. In other words each child will execute every value in the queue that comes after it. In Mike's case each child executes every [tt]unless[/tt] block that comes after it.

This is why Nathan get the extra values and Mike always gets the child from the last [tt]unless[/tt].

jaa
 
ah ..... yes .... Mike

Want to get great answers to your Tek-Tips questions? Have a look at faq219-2884

It's like this; even samurai have teddy bears, and even teddy bears get drunk.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top