2010-08-10 5 views
5

J'ai quelques blocs de code, à l'intérieur d'une fonction d'un objet, qui peuvent fonctionner en parallèle et accélérer les choses pour moi.traitement parallèle simple en perl

J'ai essayé d'utiliser subs::parallel de la manière suivante (tout cela est dans un corps d'une fonction):

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 
} 

Tout d'abord, notez que j'utilise if attendre threads pour bloquer et attendre fil avant finir quand c'est nécessaire (une meilleure idée? le if est assez moche ...).

Deuxièmement, je reçois une erreur:

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

Intéressant. Le problème est que '$ is_a_done' est vérifié dans deux threads différents, ce qui est une mauvaise utilisation/mise en garde documentée de' subs :: parallel': * Vous ne devriez pas passer à un autre thread/sous-routines parallèles J'ai lu mes valeurs. * J'avoue que je n'ai pas trouvé que la mise en garde soit très * clairement * documentée dans la version 0.8 de 'subs :: parallel', cependant. – pilcrow

Répondre

13

Je ne l'ai pas vu subs::parallel avant, mais étant donné qu'il est à faire tout le fil de manipulation pour vous, et il semble être le faire mal, basé sur le message d'erreur, je pense que c'est un peu suspect.

Normalement, je ne suggère pas simplement de le jeter comme ça, mais ce que vous faites n'est vraiment pas plus dur avec l'interface de fils simples, alors pourquoi ne pas donner un coup de feu, et simplifier le problème bit? En même temps, je vais vous donner une réponse à l'autre partie de votre question.

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. 

Vous devez quelque chose si vous êtes un peu plus complexe en utilisant les valeurs de retour de ces sous-marins (un simple passage à un hachage aiderait beaucoup) mais dans l'exemple de code que vous avez fourni, vous ne tenez pas compte eux, ce qui rend les choses faciles.

+0

J'ai créé des sous-marins au lieu d'utiliser des blocs de code (beaucoup plus propre) et j'ai mis à jour ma question à un autre légèrement différent - s'il vous plaît voir http://stackoverflow.com/questions/3448167/basic-thread-hanlding-in-perl –

Questions connexes