Perl:如何编辑Shared_Clone的结构? [英] Perl: How can I edit the structure of a shared_clone?

查看:17
本文介绍了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的结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆