use POSIX qw( _exit ); my $num_drives = 3; my $num_discs = 12; my @idle; # Idle drives my %busy; # Busy drives, keyed by the pid using them sub wait_for_a_kid { my $pid = wait(); if ($pid == -1) { warn("Can't wait: $!\n"); return 0; } ... check the child's exit code if desired ... push @idle, delete($busy{$pid}); return 1; } for my $drive (1..$num_drives) { ... eject disc ... push @idle, $drive; } my @queue = 1..$num_discs; while (@queue) { if (!@idle) { last if !wait_for_a_kid(); } my $disc = shift(@queue); my $drive = shift(@idle); my $pid = fork(); if (!defined($pid)) { warn("Can't fork: $!\n"); last; } if ($pid) { $busy{$pid} = $drive; next; } if (!eval { print("Please insert disc $disc in drive $drive\n"); ... wait for disc to be present ... ... read disc ... ... eject disc ... 1; }) { warn($@); _exit(1); } _exit(0); } while (keys(%busy)) { last if !wait_for_a_kid(); }