gpt4 book ai didi

multithreading - ithreads 可以与 Moose 惰性属性一起使用吗?

转载 作者:行者123 更新时间:2023-12-04 06:49:41 25 4
gpt4 key购买 nike

对于以下程序,我收到此错误消息:

Thread 2 terminated abnormally: Invalid value for shared scalar at reader Foo::bar (defined at ... line 9) line 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 本身是线程安全的吗(我在文档中找不到太多相关信息)?

最佳答案

Thread::Queue 用具有相同内容的共享散列和数组替换对象中的所有散列和数组,并以递归方式进行。

与此同时,您正试图更改对象。是的,那不会有好结果的。 (并不是因为 Moose、Thread::Queue 或线程中的任何错误。)

一种解决方案是以序列化形式传递对象。您可以自己处理序列化和反序列化,或者您可以使用 Thread::Queue::Any让它隐式完成。

use threads;
use Thread::Queue::Any;

my $threadq = Thread::Queue::Any->new;

sub create {
$threadq->enqueue( Foo->new ) for 1 .. 5;
$threadq->enqueue( );
}

sub process {
while ( my ($f) = $threadq->dequeue ) {
print sort keys %{$f->bar};
print "\n";
}
}

请注意,enqueuedequeue 的用法存在细微但重要的差异。最重要的是,当使用 T::Q::A 时,必须在列表上下文中调用 dequeue。这是因为 enqueue 的参数列表作为一条消息传递,而 dequeue 返回该参数列表。

关于multithreading - ithreads 可以与 Moose 惰性属性一起使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9054104/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com