對於以下程序我得到此錯誤消息:可以將ithreads與Moose懶惰屬性一起使用嗎?
線程2異常終止:在 讀者的Foo ::欄(在定義...第9行)線爲共享標值無效10.
該程序由一個管道組成,其中第一個線程創建一些基於Moose的對象並將它們放入隊列中,然後在第二個線程中將其拾取。問題似乎是該屬性是懶惰的,因爲如果我刪除懶惰設置,錯誤消失。
package Foo;
use Moose;
has 'bar' => (
is => 'ro',
isa => 'HashRef', # the error doesn't happen with simpler datatypes
lazy => 1, # this line causes the error
default => sub { return { map {$_ => $_} (1 .. 10) } },
);
package main;
use threads;
use Thread::Queue;
my $threadq = Thread::Queue->new;
sub create {
# $_ doesn't seem to be thread-safe
# this resolved another problem I had with a custom Moose type constraint
# where the 'where' clause used $_
local $_;
$threadq->enqueue(Foo->new) foreach 1 .. 5;
$threadq->enqueue(undef);
return;
}
sub process {
local $_;
while (my $f = $threadq->dequeue) {
print keys %{$f->bar}, "\n";
}
return;
}
threads->create(\&create)->join;
threads->create(\&process)->join;
誰能解釋一下這個問題嗎? Moose本身是線程安全的(我在這方面的文檔中找不到太多東西)?
那麼至少CPAN測試人員顯示穆斯測試套件與螺紋波爾斯通過結果http://www.cpantesters.org/distro/M/Moose.html#Moose-2.0401雖然我不知道什麼測試套件將執行線程。 – perigrin 2012-01-29 19:02:51
Perl可能不會將'default'中的代碼引用複製到新線程中。 – 2012-01-29 19:03:15
@BradGilbert也許,雖然同樣的錯誤也會發生,如果我更改默認''建設者',我不希望有coderef複製 – stevenl 2012-01-30 01:21:40