http://www.perlmonks.org?node_id=860786

daverave has asked for the wisdom of the Perl Monks concerning the following question:

I am using Perl 5.10.1 under Ubuntu 10.04.

This is the outline of my task. I would like to write a subroutine ('my_sub') that gets a reference to a hash of hashes (hoh). A second subroutine ('helper') will work on a single 'inner' hash.

The work on each of the internal hashes is independent of the others, so I would like to use multi-threading to speed things up.

I'm using 'Thread::Pool::Simple' which almost lacks any documentation as far as I can tell. I also looked at 'Thread::Pool', but it seems some of its dependencies are not supported by my Perl version.

The key point that I have difficulties with is the fact that I would like 'helper' to update the (inner) hash it gets. For example, I would like 'helper' to add keys to the hash.

First, I tried writing 'helper' as a subroutine that gets a (inner) hashref, so it looks something like this:

sub helper { my $href = shift; $href->{NEW_KEY}=1; }
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(); }
'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; the use it and finally return it but 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 (i.e. quit using multi-threading)
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?