我的脚本具有对象的哈希-所有单个类(SampleClass.pm)。以下是我用来创建对象的方式。

$objectHash{'foo'} = SampleClass->new();
$objectHash{'bar'} = SampleClass->new();
.
.

然后,我产生了几个线程(例如5个),每个线程都按照指示执行其工作。

现在说线程1写入一个对象-
$objectHash{'foo'}->settimeWhenISaidHello($time);

然后退出。现在,当Thread2进行工作并检查以下值时
$lastHelloTime = $objectHash{'foo'}->gettimeWhenISaidHello($time);

它获得未定义或空值。我想在线程之间共享这样的值。这怎么可能?

另外,我的类构造函数new具有哈希和哈希数组作为成员变量,如下所示。
sub new
{
.
.
listOfGuysToSayHello = {}; #This is an array with guy name as key and array value as data
SchoolsWithStudentsToSayHellow = {}; #this is array of hashes
.
.
}

此外,我已经经历了这个问题-how to access perl objects in threads,答案不符合我的要求。

请让我知道你的想法。

最佳答案

我建议首先共享一个对象不是一个好主意-可以使用threads::shared完成,但是有一些限制,您可能会引入一些竞争条件。

因此,我要说的是-使用Thread::Queue在线程之间进行通信,并使用Storablefreezethaw进行序列化。

这是一个有点简单的例子,但希望能说明这一点?也就是说,您不是在“共享”对象,而只是将它们作为序列化的数据结构传递。如果实例化对象确实改变了系统状态(例如打开与数据库的连接或类似的连接),它确实会崩溃-但这在线程上下文中本质上是很难做到的。

#!/usr/bin/env perl

use strict;
use warnings;

package MyObject;

sub new {
   my ( $class, %args ) = @_;
   my $self = \%args;
   bless $self, $class;
   return $self;
}

sub get_value {
   my ( $self, $key ) = @_;
   return $self->{$key} // 0;
}

sub set_value {
   my ( $self, $key, $value ) = @_;
   $self->{$key} = $value;
}

package main;

use threads;
use Storable qw ( freeze thaw );
use Thread::Queue;

my $work_q   = Thread::Queue->new;
my $result_q = Thread::Queue->new;

sub worker {
   while ( my $serialised = $work_q->dequeue ) {
      my $local_obj = thaw $serialised;
      print threads->self->tid, " is processing object with id ",
        $local_obj->get_value('id'), "\n";
      $local_obj->set_value( 'processed_by', threads->self->tid );
      $result_q->enqueue( freeze $local_obj );
   }
}

threads->create( \&worker ) for 1 .. 10;

for ( 1 .. 100 ) {
   my $obj = MyObject->new( id => $_ );
   $work_q->enqueue( freeze $obj );
}
$work_q->end;
$_->join for threads->list;

while ( my $ser_obj = $result_q->dequeue_nb ) {
   my $result_obj = thaw $ser_obj;
   print "Object with ID of :", $result_obj->get_value('id'),
     " was processed by thread ", $result_obj->get_value('processed_by'),
     "\n";
}

关于multithreading - Perl-如何在线程之间共享对象,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47198657/

10-11 05:40