#!/usr/bin/perl use feature ':5.18'; my @commands = (sub {say "hi"},sub {say "there"},sub {sleep 2},sub {exec("echo bye")}); my %jobs; for(@commands) { my $pid = fork(); die "bad fork" unless defined $pid; if($pid==0) { # child eval { $_->(); }; $@ and die "cmd failed: $@"; exit ($? ? $? : 0); } # parent if($pid<=0) { warn "job $_ failed ($pid): $!"; } else { $jobs{$pid}={cmd=>$_, status => "running"} } # here is where you can check for having too many jobs running if # you want to set a limit and wait for them. } # now wait for my jobs until I'm out of children. while(%jobs) { my $pid = wait(); last if($pid == -1); # no children = no more waiting next unless exists $jobs{$pid}; #if it's not a job we're watching, we don't care. #do any special handling, then... my $job = $jobs{$pid}; say "$pid ($job->{cmd}) finished with code $?"; delete $jobs{$pid}; } #continue on with the program. say "done";