our %kid; sub forkus { my $task = shift; # it's a hash ref defined(my $cpid = fork) or warn $! and return; $kid{$cpid} = $_->id, return $cpid if $cpid; exec $_->cmd; exit -1; } forkus($_) for (@first_tasks); while (%kid) { my $cpid = wait; # sleep until somebody's done forkus(next_task($cpid)) if more($cpid); # suitably defined delete $kid{$cpid}; }