可以使用shared_clone 共享复杂的数据结构。数据结构的组件在添加到它之前需要被克隆。
use strict;
use feature 'say';
use Data::Dump qw(dd);
use threads;
use threads::shared;
my $cds = {
k1 => shared_clone( { k1_l2 => [ 1..2 ] } ),
k2 => shared_clone( { k2_l2 => [10..11] } )
};
my @threads = map { async(\&proc_ds, $cds->{$_}) } keys %$cds;
$_->join() for @threads;
dd $cds;
sub proc_ds {
my ($ds) = @_;
lock $ds;
push @{$ds->{$_}}, 10+threads->tid for keys %$ds;
}
请注意,您不希望在使用共享值时允许自动激活,因为它会在结构中创建非共享(和空)组件。明确检查是否存在。
一个现成的数据结构需要被克隆和共享
my $cds = { k => [ 5..7 ] }; # already built, need be shared
my $cds_share = shared_clone( $cds );
my @threads = map { async(\&proc_ds, $cds_share) } 1..3;
$_->join() for @threads;
使用与上面相同的proc_ds() 打印结构(压缩输出)
{ 'k' => ['5', '6', '7', '11', '12', '13' ] };
当为共享而填充数据结构时,如第一个示例所示,则需要支付的开销更少。否则会涉及到数据复制,如第二个示例所示,这是否可行取决于细节(数据大小、复制频率等)。
序列化数据的想法也是可行的,但它的适用程度再次取决于细节,因为在这种情况下,您不仅会复制数据,还会复制到磁盘。
在这种情况下,JSON 无疑是一种好方法,它是一种简单易读的数据格式,也可以在工具之间共享。 Storable 是二进制的,直接与 Perl 数据结构一起工作,并且应该很快(应该显示更大的数据)。
另一种选择是使用工作模型并通过消息队列传递数据。然后你可以使用Thread::Queue,或者使用Thread::Queue::Any,作为沟通渠道。