Non-blocking waiting, rerun on failure
In this example we have a list of tasks we need to do. The user can supply the number of child processes that will deal with the tasks.
Each child process generates a random number to wait to imitatet the work time and a random number as the exit code.
The parent monitors the child processes. If one of them exits with a non-zero error code the parent re-runs that job with another child process until all the tasks are done.
examples/forks/active_waiting_tasks.pl
use strict; use warnings; use Time::HiRes qw(sleep); use POSIX ':sys_wait_h'; main(); sub main { my ($workers) = @ARGV; die "Usage: $0 WORKERS\n" if not defined $workers; #my @tasks = 'a' .. 'z'; my @tasks = 'a' .. 'd'; my %process; while (1) { if (@tasks and scalar(keys %process) < $workers) { my $task = shift @tasks; my $pid = fork(); die 'Failed to fork' if not defined $pid; if ($pid == 0) { my $exit_code = int rand(3); my $sleep_time = rand(5); print "Child process Task: $task PID $$ will sleep for $sleep_time and then exit with code $exit_code\n"; sleep $sleep_time; exit $exit_code; } $process{$pid} = $task; next; } my $pid = waitpid(-1, WNOHANG); if ($pid > 0) { my $exit_code = $?/256; my $task = delete $process{$pid}; print "Child process $pid task $task finished with exit code $exit_code\n"; if ($exit_code > 0) { unshift @tasks, $task; } next; } sleep 0.1; last if not %process; } }
Child process Task: a PID 128387 will sleep for 3.71995377981634 and then exit with code 2 Child process Task: b PID 128388 will sleep for 0.137503658640838 and then exit with code 0 Child process Task: c PID 128389 will sleep for 3.57264931009681 and then exit with code 1 Child process 128388 task b finished with exit code 0 Child process Task: d PID 128390 will sleep for 0.940422063447244 and then exit with code 0 Child process 128390 task d finished with exit code 0 Child process 128387 task a finished with exit code 2 Child process 128389 task c finished with exit code 1 Child process Task: a PID 128391 will sleep for 3.09917882712156 and then exit with code 2 Child process Task: c PID 128392 will sleep for 1.52811677938857 and then exit with code 2 Child process 128392 task c finished with exit code 2 Child process Task: c PID 128393 will sleep for 1.21268558593997 and then exit with code 0 Child process 128393 task c finished with exit code 0 Child process 128391 task a finished with exit code 2 Child process Task: a PID 128394 will sleep for 2.05004244389542 and then exit with code 2 Child process 128394 task a finished with exit code 2 Child process Task: a PID 128395 will sleep for 4.95541832222202 and then exit with code 0 Child process 128395 task a finished with exit code 0