如何在多线程perl中共享哈希引用?

时间:2014-10-28 16:00:50

标签: multithreading perl thread-safety

如何跨主线程和工作线程共享哈希引用$ref

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

use threads;
use threads::shared;

my $ref = {};
$ref->{0}->{abc} = 123;
$ref->{1}->{abc} = 223;

printf( "%d\n", $ref->{0}->{abc} );
printf( "%d\n", $ref->{1}->{abc} );

issue_all_jobs($ref);

while (1)
{
    printf( "%d\n", $ref->{0}->{abc} );
    printf( "%d\n", $ref->{1}->{abc} );
    sleep(1);
}

sub issue_all_jobs
{
    my ($ref) = @_;
    for ( my $i = 0; $i < 2; $i++ )
    {
        $ref->{$i}->{handle} = new threads( \&issue_job, $ref, $i );
        $ref->{$i}->{handle}->detach();
    }
}

sub issue_job
{
    my ( $ref, $i ) = @_;
    $ref->{$i}->{abc} = 555123 + $i;
    sleep(2);
}

1 个答案:

答案 0 :(得分:5)

这不像您想象的那样有效。 threads::shared的一个限制是它可以很好地共享单维容器,但是在尝试处理嵌套数据结构时它会变得相当混乱,因为编译器不知道它需要共享什么。

http://perldoc.perl.org/threads/shared.html#BUGS-AND-LIMITATIONS

所以 - 对于初学者 - 您需要首先将共享变量指定为共享。要么声明:

my $ref : shared;

但是当你试图分享哈希

shared_clone ( $ref ); 

但就个人而言 - 我会回避这些事情。我不喜欢使用共享内存对象,并且通常更喜欢使用Thread::SemaphoreThread::Queue并在队列中来回传递数据。 Storable对此有很大帮助,因为您可以freezethaw数据对象插入队列。