#!/usr/bin/perl # https://perlmonks.org/?node_id=1217948 use strict; use warnings; use Data::Dump 'dd'; use Storable qw( freeze thaw ); use Time::HiRes qw( time sleep ); use IO::Select; my $maxforks = 20; my @ids = 'job01' .. 'job38'; # it is cool that this works my $sel = IO::Select->new; my $start = time; my @answers; while( @ids or $sel->count ) # unstarted or active { while( @ids and $sel->count < $maxforks ) # start all forks allowed { my $id = shift @ids; if( open my $fh, '-|' ) # forking open { $sel->add( $fh ); # parent } else # child code goes here { sleep rand; print freeze { id => $id, pid => $$, time => time - $start }; exit; } } for my $fh ( $sel->can_read ) # collecting child data { local $/; push @answers, thaw <$fh>; $sel->remove( $fh ); } } dd \@answers;