我正在尝试运行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;
}
答案 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"之前,将返回空值。