本文介绍了Perl:如何编辑Shared_Clone的结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
在this问题之后,我面临以下问题:
当我希望循环几个线程中的一些散列并更新它们时,我收到以下错误:
Thread .. terminated abnormally: Invalid value for shared scalar at ...
代码如下:
use feature qw(say);
use strict;
use warnings;
use threads ;
use threads::shared ;
use Data::Dumper qw(Dumper);
my %h1 = (a => 1, b => 2);
my %h2 = (c => 3, d => 4);
my $a1 = \%h1;
my $b1 = \%h2;
my $a1c = shared_clone($a1);
my $b1c = shared_clone($b1);
my $lockvar:shared;
my $nthreads = 3;
for ( 1..$nthreads ) {
threads->create('job_to_parallelize', $a1c, $b1c, $lockvar ) ;
}
$_->join() for threads->list();
sub job_to_parallelize {
my ($a1, $b1, $lockvar) = @_;
{
lock $lockvar;
$a1->{a}++;
$b1->{d}++;
$a1->{scalar}{10} = 1;
}
}
print Dumper($a1c);
print Dumper($b1c);
据我所知,这是因为在我克隆之前,标量和标量还不存在。你知道怎么解决这个问题吗?(即,允许我在克隆结构上声明内部线程)。
推荐答案
问题是$a1->{scalar}{10} = 1
创建一个新的散列,该散列存储在$a1->{scalar}
中,并且有一个键(10
),其值为1
。这个新的散列不是共享的(您从未共享过它),因此出现了问题。要解决该问题,您需要共享这个新的散列。例如:
$a1->{scalar} //= shared_clone {} ;
$a1->{scalar}{10} = 1;
也可以写成:
($a1->{scalar} //= shared_clone {} )->{10} = 1;
我认识到这有点乏味,特别是当您有大量数据要共享时。如果不从不同的线程更新相同的密钥,那么可以在线程内创建任意复杂的散列,并在最后共享它们。例如,
sub job_to_parallelize {
my ($a1, $b1, $lockvar) = @_;
my %thr_data = (key1 => 'data1',
key2 => { inside => 42 });
$a1->{threads->tid} = shared_clone(\%thr_data);
}
即使您确实更新了线程中的相同键,您也可以使用此方法并在末尾重新组合散列,例如使用Hash::Merge
。
这篇关于Perl:如何编辑Shared_Clone的结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!