2010-08-10 9 views
5

Tengo algunos bloques de código, dentro de una función de algún objeto, que pueden correr en paralelo y acelerar las cosas para mí.procesamiento paralelo simple en perl

He intentado utilizar subs::parallel de la siguiente manera (todo esto es en un cuerpo de una función):

my $is_a_done = parallelize { 
           # block a, do some work 
           return 1; 
          }; 
my $is_b_done = parallelize { 
           # block b, do some work 
           return 1; 
          }; 
my $is_c_done = parallelize { 
           # block c depends on a so let's wait (block) 
           if ($is_a_done) { 
           # do some work 
           }; 
           return 1; 
          }; 
my $is_d_done = parallelize { 
           # block d, do some work 
           return 1; 
          }; 

if ($is_a_done && $is_b_done && $is_c_done && $is_d_done) { 
# just wait for all to finish before the function returns 
} 

En primer lugar, observe que uso if que esperar a que las discusiones para bloquear y esperar hilo anterior a terminar cuando sea necesario (una mejor idea? el if es bastante feo ...).

En segundo lugar, me sale un error:

Thread already joined at /usr/local/share/perl/5.10.1/subs/parallel.pm line 259. 
Perl exited with active threads: 
    1 running and unjoined 
    -1 finished and unjoined 
    3 running and detached 
+0

Interesante. El problema es que '$ is_a_done' se comprueba en dos subprocesos diferentes, que es un mal uso/advertencia documentado de' subs :: parallel': * No debe pasar a otro subproceso/subrutinas en paralelo valores devueltos anteriores de otras subrutinas paralelizadas sin leyendo sus valores. * Admito que no encontré la advertencia de estar muy * claramente * documentada en la versión 0.8 de 'subs :: parallel', sin embargo. – pilcrow

Respuesta

13

No he visto subs::parallel antes, pero teniendo en cuenta que se está haciendo todo el manejo para que el hilo, y parece estar haciéndolo mal, basado en el mensaje de error, creo que es un poco sospechoso.

Normalmente no recomendaría tirarlo así, pero lo que está haciendo realmente no es ningún más difícil con la interfaz de hilos lisos, así que ¿por qué no darle una oportunidad y simplificar el problema de una ¿poco? Al mismo tiempo, le daré una respuesta a la otra parte de su pregunta.

use threads; 
my @jobs; 
push @jobs, threads->create(sub { 
    # do some work 
}); 

push @jobs, threads->create(sub { 
    # do some other work 
}); 

# Repeat as necessary :) 

$_->join for @jobs; # Wait for everything to finish. 

necesita algo un poco más complicado si está usando los valores de retorno de esos submarinos (simplemente cambiando a un hash ayudaría mucho), pero en el ejemplo de código que ya ha proporcionado, estás ignorando ellos, lo que hace las cosas fáciles.

+0

Creé submarinos en lugar de usar bloques de código (se ve mucho más limpio) y actualicé mi pregunta a una ligeramente diferente - vea http://stackoverflow.com/questions/3448167/basic-thread-hanlding-in-perl –

Cuestiones relacionadas