对于以下程序我得到此错误消息:可以将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