2010-09-13 39 views
8

我想在多个线程上共享多维散列。 这个散列保存2个连接的密钥对,我需要知道它们是否已经连接,如果它们不是,我需要连接它们,如果没有,则不需要去数据库。Perl:共享多维散列的线程化

use threads; 
use threads::shared; 

my %FLUobject2param : shared =(); 

#Start a new thread for every available processor 
for (my $i=0;$i<$PROCESSORS;$i++) { 
    threads->new(\&handlethread); 
} 
#Catch if these threads end 
foreach my $onthr (threads->list()) { 
    $onthr->join(); 
} 

sub handlethread{ 
    ... 
    if(not defined $FLUobject2param{$objectID}{$paramID}){ 
     $dbh->getObject2Param($objectID,$paramID); 
     $FLUobject2param{$objectID}{$paramID} = 1; 
    } 
} 

我不断收到错误Invalid value for shared scalar上线
if(not defined $FLUobject2param{$objectID}{$paramID}){

这显然与Perl的线程共享::只允许您共享共享结构的单一层次的事。

我该如何仍然能够检查这个组合是否已经用于多个线程?

回答

8

Autovivification大部分时间都是你的朋友,但你必须小心谨慎,共享价值观。修改handlethread

sub handlethread{ 
    # ... 
    unless (exists $FLUobject2param{$objectID} && 
      exists $FLUobject2param{$objectID}{$paramID}) 
    { 
     $dbh->getObject2Param($objectID,$paramID); 
     $FLUobject2param{$objectID} = &share({}); 
     $FLUobject2param{$objectID}{$paramID} = 1; 
    } 
} 

这是由于做documented limitation

共享变量只能存储标量,共享变量,或共享数据的参考文献的参考文献...上面

的代码分别检查散列键以避免自动版本化,如果它尚不存在,将在$FLUobject2param{$objectID}中植入一个非共享空的散列引用。

在条件内部,我们首先构建适当的脚手架,然后分配值。再次,autovivification通常为您处理这个问题,但分享迫使我们更加慎重。