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?