Multithreading 线程中的Perl哈希引用正在更改

Multithreading 线程中的Perl哈希引用正在更改,multithreading,perl,hash,hashref,Multithreading,Perl,Hash,Hashref,我使用perl和线程来处理套接字信息 连接线 负责接收数据包和解析,并在散列中加密 排队线程 负责处理队列元素(散列项)和更新数据库 散列为事件并声明为my%Events:shared 我正在向线程传递一个hash引用,但是我注意到每个线程都得到一个不同的hash ref值 my $hash_ref1 = \%Events ; # referencing print "Hash ref in main is 1 " . $hash_ref1 ."\n"; my $thr1 = threads-&

我使用perl和线程来处理套接字信息

连接线 负责接收数据包和解析,并在散列中加密

排队线程 负责处理队列元素(散列项)和更新数据库

散列为事件并声明为my%Events:shared

我正在向线程传递一个hash引用,但是我注意到每个线程都得到一个不同的hash ref值

my $hash_ref1 = \%Events ; # referencing
print "Hash ref in main is 1 " . $hash_ref1 ."\n";
my $thr1 = threads->create(\&ConnectionThread, $hash_ref1 );
my $thr2 = threads->create(\&QueueThread, $hash_ref1);
输出如下所示

Hash ref in main is 1 HASH(0x825faa4)
Hash ref is ConnectionThread is HASH(0x8493544)
Thread started ..
Hash ref is Queue thread is HASH(0x852dd9c)
下面是完整的代码(说明性的)


是的,这会发生。线程不共享内存。您可以使用
shared
对其进行排序,这允许您使用公共变量,但您不一定会看到相同的哈希内存位置

尽管
%Events
共享的
,但如果
打印\%Events,则不会在每个线程中打印相同的内存地址


鉴于您正在谈论排队,我建议您改为使用
Thread::Queue
,它允许您以一种非常简单且线程安全的方式“执行”队列/出列操作

您不是在所有线程中直接访问同一个变量。如果您这样做了,那么您必须明确保证每次访问变量时(即使只是读取变量)都能相互访问该变量,以避免程序崩溃

每个线程(包括创建变量的线程)都会获得一个 “代理”到包含变量的数据。代理是一个神奇的变量,这意味着访问代理的元素会导致调用getter和setter。这些getter和setter通过提供互斥访问来确保包含变量的数据永远不会处于不一致的状态

$ perl -Mthreads -Mthreads::shared -MDevel::Peek \
   -E'my %h :shared; ( async { Dump(%h); } )->join; Dump(%h);' 2>&1 |
      grep -P '^\S|^ {8}IV'
SV = PVHV(0x1ed5f90) at 0x1f6fd68   <-----+
        IV = 31930352               <--+  |
SV = PVHV(0x1d70af0) at 0x1d880d0   <--|--+------ Two different vars
        IV = 31930352               <--+--------- Proxying the same var (0x1e737f0)
$perl-Mthreads-Mthreads::shared-MDevel::Peek\
-E'my%h:共享;(异步{Dump(%h);})->join;转储(%h);'2>&1 |
grep-P'^\S ^{8}IV'

SV=0x1f6fd68处的PVHV(0x1ed5f90)这只是为了满足您的好奇心吗?
$ perl -Mthreads -Mthreads::shared -MDevel::Peek \
   -E'my %h :shared; ( async { Dump(%h); } )->join; Dump(%h);' 2>&1 |
      grep -P '^\S|^ {8}IV'
SV = PVHV(0x1ed5f90) at 0x1f6fd68   <-----+
        IV = 31930352               <--+  |
SV = PVHV(0x1d70af0) at 0x1d880d0   <--|--+------ Two different vars
        IV = 31930352               <--+--------- Proxying the same var (0x1e737f0)