我喜歡在線程之間共享複雜數據結構。 據我所知,這是不可能的線程:共享(只有基本類型是可共享的)。Perl:在線程之間共享複雜數據結構
所以我想用JSON或Storable對序列化/反序列化結構,所以它只是一個字符串,我可以完美地共享。但是我需要在使用前將其打開並在更改後將其打包。
這是一種常見的解決方法嗎?
有沒有更好的方法?
您是否更喜歡JSON或可存儲或其他?
感謝您的幫助!
編輯
我只是做了一些測試與可存儲和JSON。 JSON更快,生成更小的序列化字符串。我原本沒想到。
我喜歡在線程之間共享複雜數據結構。 據我所知,這是不可能的線程:共享(只有基本類型是可共享的)。Perl:在線程之間共享複雜數據結構
所以我想用JSON或Storable對序列化/反序列化結構,所以它只是一個字符串,我可以完美地共享。但是我需要在使用前將其打開並在更改後將其打包。
這是一種常見的解決方法嗎?
有沒有更好的方法?
您是否更喜歡JSON或可存儲或其他?
感謝您的幫助!
編輯
我只是做了一些測試與可存儲和JSON。 JSON更快,生成更小的序列化字符串。我原本沒想到。
可以使用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' ] };
@ chris01添加了一個可能更重要的示例 – zdim
當處理這個問題,我使用Thread::Queue
來傳遞我的物體,並且通常使用Storable
來連續化。
我還沒有打擾過性能的比較,因爲通常是我的數據傳遞開銷並不是限制因素。
注 - Storable
的主要優點是,它允許一些有限的對象的支持(不 - 要小心 - 它只有作品,如果你的對象包含個體經營):
#!/usr/bin/env perl
use strict;
use warnings;
package MyObject;
sub new {
my ($class, $id) = @_;
my $self = {};
$self -> {id} = $id;
$self -> {access_count} = 0;
bless $self, $class;
return $self;
}
sub access_thing {
my ($self) = @_;
return $self -> {access_count}++;
}
sub get_id {
my ($self) = @_;
return $self -> {id};
}
package main;
use threads;
use Thread::Queue;
use Storable qw (freeze thaw);
my $thread_count = 10;
my $work_q = Thread::Queue -> new;
sub worker {
while (my $item = $work_q -> dequeue) {
my $obj = thaw ($item);
print $obj -> get_id, ": ", $obj -> access_thing,"\n";
}
}
for (1..$thread_count) {
threads -> create (\&worker);
}
for my $id (0..1000) {
my $obj = MyObject -> new ($id);
$work_q -> enqueue (freeze ($obj));
}
$work_q -> end;
$_ -> join for threads -> list;
如果JSON會限制你到數組/散列數據結構 - 這可能適合您的使用情況。
您可以使用'shared_clone'共享複雜的數據結構,但是您需要在將組件添加到結構之前克隆組件(無法「共享」現成的組件)。那是合適的嗎? – zdim
如果發生這種情況,請參閱[當某人回答我的問題時該怎麼辦?](http://stackoverflow.com/help/someone-answers) – zdim