Listing 2: The do_stats() function is responsible for launching the timing tests sub do_stats { my $doit = shift; my $start = time(); # open a pipe so that child processes can send results to parent. my $pipe = IO::Pipe->new || die "Can't pipe: $!"; # spawn correct number of children for (my $i=0; $i<$COPIES; $i++) { die "Can't fork: $!" unless defined (my $pid = fork()); # if parent, continue spawning children next if $pid > 0; # otherwise we're a child, so we run the test once and exit $pipe->writer; select $pipe; run_test($doit); exit 0; } # otherwise, parent reads and tallies the results $SIG{CHLD} = sub { do {} while waitpid(-1,WNOHANG) > 0; }; # open pipe for reading $pipe->reader; my $stats = tally_results($pipe); $stats->{elapsed} = time() - $start; return $stats; }