Как мне обновить хэш хэшей при использовании многопоточности в Perl?

Я провел последние часы, пытаясь понять это, и теперь я действительно сбит с толку.

Это схема моей задачи. Я должен написать подпрограмму Perl, которая получает ссылку на хэш хэшей.

У меня есть еще одна подпрограмма (helper), которая получает один внутренний хэш и выполняет некоторые действия, включая добавление ключей.

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

Поскольку каждый из внутренних хэшей независим от других, я хотел бы использовать многопоточность для вызова helper.

Я использую Thread::Pool::Simple, в котором практически отсутствует какая-либо документация. Thread::Pool не поддерживается моей версией Perl.

Итак, у меня есть что-то вроде этого:

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 получает неразделенную ссылку на $hohref, поэтому я попытался создать общую копию в теле my_sub:

my $shared_hohref = shared_clone $hohref;

используйте его и верните вместо этого, но все же внутренние хэши не были обновлены.

Когда я использую точно такой же код, но просто заменяю весь блок пула потоков простым циклом

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

тогда все работает нормально.

Ваша помощь будет принята с благодарностью.

ОБНОВЛЕНИЕ

См. этот работающий пример:

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;

'помощник запускается', но это все... что с ним происходит?


person David B    schedule 20.09.2010    source источник


Ответы (1)


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

person David B    schedule 28.09.2010