Perl:使用共享的多维散列进行线程处理 [英] Perl: Threading with shared multi-dimensional hash

查看:252
本文介绍了Perl:使用共享的多维散列进行线程处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 使用线程; 
使用threads :: shared;

my%FLUobject2param:shared =();

#为每个可用处理器启动一个新线程
(my $ i = 0; $ i <$ PROCESSORS; $ i ++){
threads-> new(\\ \\&安培; handlethread);
}
#Catch如果这些线程结束
foreach my $ onthr(threads-> list()){
$ onthr-> join();


子句柄线程{
...
if(未定义$ FLUobject2param {$ objectID} {$ paramID}){
$ dbh- > getObject2Param($的objectID,$芳族聚酰胺);
$ FLUobject2param {$ objectID} {$ paramID} = 1;


$ / code>

我不断收到错误如果(未定义的$ FLUobject2param {$ objectID} {$ paramID}){行上共享标量的值无效

$ b

这显然与perl的线程::共享有关,只允许你共享一个共享结构级别。



我怎么会仍然能够检查这个组合是否已经在多个线程中使用?

解决方案

Autovivification是大多数时候你的朋友,但你必须小心与共享的价值观。修改 handlethread

  sub handlethread {
#.. 。
除非(存在$ FLUobject2param {$ objectID}&&
exists $ FLUobject2param {$ objectID} {$ paramID})
{
$ dbh-> getObject2Param( $的objectID,$芳族聚酰胺);
$ FLUobject2param {$ objectID} =& share({});
$ FLUobject2param {$ objectID} {$ paramID} = 1;


$ / code $ / pre
$ b $ p

这是由于记录的限制


共享变量只能存储标量,共享变量的引用或共享数据的引用...

上面的代码检查散列键分开以避免autovivification,如果它还不存在,它将在 $ FLUobject2param {$ objectID} 中植入一个非共享的空散列引用。



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


I am trying to share a multi-dimensional hash over multiple threads. This hash holds 2 connected key-pairs, I need to know if they are already connected, if they are not, I need to connect them, if not, there is no need to go to the database.

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;
    }
}

I keep getting the error Invalid value for shared scalar on the line
if(not defined $FLUobject2param{$objectID}{$paramID}){

This apparently has to do with perl's threads::shared only allowing you to share a single level of shared structure.

How would I still be able to check if this combination is already used over multiple threads ?

解决方案

Autovivification is your friend most of the time, but you have to be careful about it with shared values. Modify handlethread:

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

This is due do a documented limitation:

Shared variables can only store scalars, refs of shared variables, or refs of shared data …

The code above checks the hash keys separately to avoid autovivification, which will plant an unshared empty hash reference in $FLUobject2param{$objectID} if it doesn't exist yet.

Inside the conditional, we first build the appropriate scaffolding and then assign the value. Again, autovivification ordinarily handles this for you, but sharing forces us to be more deliberate.

这篇关于Perl:使用共享的多维散列进行线程处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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