Perl MCE将哈希数据返回给主进程

时间:2015-01-09 07:57:06

标签: multithreading perl hash subroutine

我正在尝试运行Perl Many-Core Engine,它运行良好。但是当工作人员将数据添加到子例程中的全局哈希时,一旦MCE过程完成,该数据就会丢失(请参阅下面注释的位置)。我不认为这会是一个问题,因为%data是全局的。任何建议都非常感激。

#!/usr/bin/perl
use strict;
use warnings;
use MCE;

my @symbol = ('abc','def');
my $CPUs = 1;
my %data = ();

process();

sub process {
    my $mce = MCE->new(
        input_data  => \@symbol,
        max_workers => $CPUs,
        user_func => sub {
            my ($self, $sym, $chunk_id) = @_;
            $sym = $sym->[0];
            doTask($sym);
        }
    );
    $mce->run();

    print %data; # if I check contents of %data at this line in the code, its empty
}

sub doTask {
    my ($sym) = @_;
    $data{$sym} = 1;

    print %data;
    print "\n\n";

    return;
}

4 个答案:

答案 0 :(得分:1)

使用MCE :: Map模型可以正常工作,它具有内置的数据收集功能。

#!/usr/bin/perl
use strict;
use warnings;
use MCE::Map;

my @symbol = ('abc','def');
my $CPUs = 1;
my %data = ();

process();

sub process {
    MCE::Map::init {chunk_size => 1, max_workers => $CPUs};
    %data = mce_map {doTask($_)} @symbol;
    print %data; # data exchange between the manager and worker processes works
}

sub doTask {
    my ($sym) = @_;
    $data{$sym} = 1;
    return %data;
}

答案 1 :(得分:1)

即将推出的MCE 1.7版本将包含支持深度共享的完整数据共享功能。

use MCE;
use MCE::Shared;

mce_share my %data;

哈希在支持进程和线程的工作者之间共享。

答案 2 :(得分:0)

doTask真的运行吗?它looks like user_func应该是user_tasks的一部分:

my $mce = MCE->new(
    input_data  => \@symbol,
    user_tasks  => [{
        max_workers => $CPUs,
        user_func   => sub {
            my ($self, $sym, $chunk_id) = @_;
            $sym = $sym->[0];
            doTask($sym);
    }]
);
$mce->run();

答案 3 :(得分:-1)

要在所有线程之间返回或共享复杂的结构,例如arrary的散列哈希,MCE foreach或带有collect的MCE :: Loop,测试不起作用。 MCE :: Map都没有。唯一经过测试的工作方式是通过threads :: share,通过递归添加共享子层,如http://www.perlmonks.org/?node_id=798735所示,并使用shared_clone进行结束分配。

# the following lines cannot be ommitted otherwise error "Invalid value for shared scalar"
unless (exists $HoH{$F[0]})
{
my %p : shared;
$HoH{$F[0]} = \%p;
}
# the following lines if skipped will randomly missing a few records
unless (exists $HoH{$F[0]}{$mf})
{
    my @c : shared;
    $HoH{$F[0]}{$mf} = \@c;
}  
$HoH{$F[0]}{$mf}=shared_clone([$F[3],$F[4]]);
#we cannot use $HoH{$mf}=shared_clone(\%Loss) directly, where %Loss is a hash of arrary
BTW,此方法仅在作为独立脚本运行时才起作用,如果从perl调试器中运行,则不允许"使用线程"在"使用threads :: shared"之前,将返回空值。