I have been spending the last hours trying to figure this out and now I'm really confused.
This is the outline of my task. I should write a Perl subroutine that gets a reference to a hash of hashes.
I have another sub (helper
) that gets a single inner hash and does some stuff to with, including adding keys.
sub helper {
$href = shift;
$href->{NEW_KEY}=1;
}
Since each of the internal hashes is independent of the others, I would like to use multi-threading to call helper
.
I'm using Thread::Pool::Simple
which almost lacks any documentation. Thread::Pool
is not supported by my Perl version.
So I have something like this:
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();
}
The key point is that I would like the main hash of hashes to reflect all the changes made to the inner hashes.
my_sub
gets an unshared reference to $hohref
so I tried creating a shared copy in the body of my_sub
:
my $shared_hohref = shared_clone $hohref;
use it and return it instead, but still, the internal hashes were not updated.
When I use the exact same code, but simply replace all the thread pool block with a simple loop
foreach my $hashref ( values %{$hohref} ) {
helper( $hashref );
}
then everything works fine.
Your help would be greatly appreciated.
UPDATE
See this runnable example:
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;
'helper starts' but that's it... what ever happens to it?