2010-09-13 74 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通常爲您處理這個問題,但分享迫使我們更加慎重。