views:

59

answers:

1

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?

A: 

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

David B