2010-09-20 3 views
2

J'ai passé les dernières heures à essayer de comprendre cela et maintenant je suis vraiment confus.Comment mettre à jour un hachage de hachages lors de l'utilisation de multi-threads en Perl?

Voici le contour de ma tâche. Je devrais écrire un sous-programme Perl qui obtient une référence à un hachage de hachages.

J'ai un autre sub (helper) qui obtient un seul hachage interne et fait des choses avec, y compris l'ajout de clés.

sub helper { 
    $href = shift; 
    $href->{NEW_KEY}=1; 
} 

Comme chacun des hash internes est indépendant des autres, je voudrais utiliser le multi-threading pour appeler helper. J'utilise Thread::Pool::Simple qui manque presque de documentation. Thread::Pool n'est pas supporté par ma version Perl.

J'ai donc quelque chose comme ceci:

sub my_sub { 
    $hohref = shift; 

    # create thread pool 
    my $pool = Thread::Pool::Simple->new(
     do => [ \&helper ] 
    ); 

    # submit jobs 
    foreach my $hashref (values %{$hohref}) { 
     $pool->add($hashref); 
    } 

    # wait for all threads to end 
    $pool->join(); 
} 

Le point clé est que je voudrais que le hachage principal de hash pour refléter toutes les modifications apportées aux hash internes.

my_sub obtient une référence à unshared $hohref donc j'ai essayé de créer une copie partagée dans le corps de my_sub:

my $shared_hohref = shared_clone $hohref; 

l'utiliser et de le retourner à la place, mais encore, les hash internes ont été pas mises à jour.

Lorsque j'utilise exactement le même code, mais suffit simplement de remplacer le bloc de pool de threads avec une simple boucle

foreach my $hashref (values %{$hohref}) { 
    helper($hashref); 
} 

alors tout fonctionne très bien.

Votre aide serait grandement appréciée.

MISE À JOUR

Voir cet exemple runnable:

use strict; 
use warnings; 

use threads; 
use threads::shared; 

use Thread::Pool::Simple; 
use 5.010; 

use Data::Dumper; 

sub helper { 
    say "helper starts"; 
    my $href = shift; 
    say "href is $href"; 
    $href->{NEW_KEY} = 1; 
    say "helper ends with $href"; 
} 


sub my_sub { 
    my $hohref = shift; 

    my $shared_hohref = shared_clone $hohref; 
    my $pool = Thread::Pool::Simple->new(do => [\&helper]); 

    # submit jobs 
    foreach my $hashref (values %{$shared_hohref}) { 
     say "adding to pool: $hashref"; 
     $pool->add($hashref); 
    } 

    # wait for all threads to end 
    $pool->join(); 

    return $shared_hohref; 
} 

my $hoh = { 
    A => { NAME => "a" }, 
    B => { NAME => "bb" } 
}; 

say "1\t", Dumper $hoh; 
my $updated_hoh = my_sub($hoh); 
say "2\t", Dumper $updated_hoh; 

'aide commence', mais c'est tout ce qui se passe ... jamais il?

Répondre

Questions connexes