Для приведенной ниже программы я получаю это сообщение об ошибке:
Поток 2 завершен ненормально: неверное значение для общего скаляра в
читатель Foo :: bar (определяется в ... строке 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 сам по себе многопоточным (я не мог найти много в документации по этому поводу)?