Perl: многопоточность с общим многомерным хешем - PullRequest
8 голосов
/ 13 сентября 2010

Я пытаюсь разделить многомерный хэш на несколько потоков. Этот хэш содержит 2 подключенные пары ключей, мне нужно знать, если они уже подключены, если нет, мне нужно подключить их, если нет, нет необходимости переходить в базу данных.

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 :: shared, позволяющими вам использовать общий уровень общей структуры.

Как бы я смог проверить, используется ли эта комбинация в нескольких потоках?

1 Ответ

8 голосов
/ 13 сентября 2010

Автовификация - ваш друг большую часть времени, но вы должны быть осторожны с общими ценностями. Изменить handlethread:

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

Это связано с задокументированным ограничением :

Общие переменные могут хранить только скаляры, ссылки на общие переменные или ссылки на общие данные ...

Приведенный выше код проверяет ключи хеширования отдельно, чтобы избежать автовивификации, которая создаст неразделенную ссылку на пустой хеш в $FLUobject2param{$objectID}, если она еще не существует.

Внутри условного выражения мы сначала строим соответствующие строительные леса, а затем присваиваем значение. Опять же, автовивификация обычно справляется с этим для вас, но обмен заставляет нас быть более осознанными.

...