Here's the pattern I used for that on a recent project -- it's a bit more robust than yours.
use POSIX ":sys_wait_h";
my @tasks = (1..398);
my %kids;
{
while (@tasks and keys %kids < 5) {
$kids{fork_a_task(shift @tasks)} = "active";
}
{
my $pid = waitpid(-1, 0);
if ($pid == -1) {
%kids = ();
} else {
delete $kids{$pid};
}
}
redo if @tasks or %kids;
}
sub fork_a_task {
my $i = shift;
my $pid = fork;
return $pid if $pid;
unless (defined $pid) {
warn "cannot fork: $!";
return 0;
}
## do stuff for task $i goes here...
exit 0;
}
-- Randal L. Schwartz, Perl hacker
Be sure to read my standard disclaimer if this is a reply.