use Proc::Simple;
$| = 1;                                 # debuffer output
$max_parallel_jobs = 5;                 # jobs processed in parallel
@running = ();                          # array of running jobs
foreach $job (1..9) {                   # create pseudo jobs
    push(@todo, "sleep 3"); 
}                                       
######################################################################
                                        # while there are jobs to do
while($#todo >= 0 || $#running >= 0) {  # or started ones are running
    @running = grep { $_->poll() } @running;  # remove finished jobs
    if($#running + 1 < $max_parallel_jobs &&  # space free in running?
       defined($job = pop(@todo))) {          # ... and job available
        print "Starting job '$job' ... ";
        $proc = Proc::Simple->new();    # new process
        $proc->start($job) || die "Cannot start job $job";
        push(@running, $proc);          # include in running list
    
        print "STARTED. (Remaining: ", $#todo+1, 
              " Running: ", $#running + 1, ")\n";
        next;                           # proceed without delay
    }
    sleep(1);                           # pause ... and proceed
}
Cuando se ejecuta, produce esta salida:
$ perl eg/parproc.pl Starting job 'sleep 3' ... STARTED. (Remaining: 8 Running: 1) Starting job 'sleep 3' ... STARTED. (Remaining: 7 Running: 2) Starting job 'sleep 3' ... STARTED. (Remaining: 6 Running: 3) Starting job 'sleep 3' ... STARTED. (Remaining: 5 Running: 4) Starting job 'sleep 3' ... STARTED. (Remaining: 4 Running: 5) Starting job 'sleep 3' ... STARTED. (Remaining: 3 Running: 5) Starting job 'sleep 3' ... STARTED. (Remaining: 2 Running: 5) Starting job 'sleep 3' ... STARTED. (Remaining: 1 Running: 3) Starting job 'sleep 3' ... STARTED. (Remaining: 0 Running: 4)Basándose en Proc::Simple escriba un módulo
Proc::RPC que de funcionalidades
similares:
Posibles Consideraciones:
start para un objeto sobre el que hay un proceso ya arrancado?
use vars qw(%EXIT_STATUS %INTERVAL %DESTROYED) ¿Es posible reconvertir las variables globales de paquete a variables léxicas?
start y añadir un método join similar a wait
pero que para los procesos hijo
que ejecutan código Perl retorna una estructura de datos Perl. Usando la API de 
Proc::Simple::Async
podría ser utilizada así:
    $proc = async { map { $_ * $_ } @_  } , 1..3;
    ...
    my @r = $proc->join(); # @r es ahora (1, 4, 9)
Puede usar Data::Dumper
o Storable
para serializar los datos retornados.
Para ello deberá modificar el método start de Proc::Simple:
sub start {
  my $self  = shift;
  my ($func, @params) = @_;
  # Reap Zombies automatically
  $SIG{'CHLD'} = \&THE_REAPER;
  # Fork a child process
  $self->{'pid'} = fork();
  return 0 unless defined $self->{'pid'};  #   return Error if fork failed
  if($self->{pid} == 0) { # Child
      if (defined $self->{'redirect_stderr'}) { ...  }
      if (defined $self->{'redirect_stdout'}) { ...  }
      if(ref($func) eq "CODE") {
        my @r = $func->(@params); 
        #  Serialize @r in a temp file using Data::Dumper o Storable u otro ...
        $self->serialize(@r);
        exit 0;            # Start perl subroutine
      } else {
          exec $func, @params;       # Start shell process
          exit 0;                    # In case something goes wrong
      }
  } elsif($self->{'pid'} > 0) {      # Parent:
      ...
  } else {      
      return 0;                      #   this shouldn't occur
  }
}
El método join funciona como el método wait pero lee y evalúa
los contenidos del fichero generado por el proceso hijo.
Es posible que necesite atributos adicionales para guardar el nombre del fichero 
mediante el que se comunicarán padre e hijo.
Casiano Rodríguez León
