perl - 如何通过 Lazy 属性和 Coro 防止 Moose 中的竞争状况

标签 perl moose

我们正在进行的项目使用 Coro 进行异步处理,不幸的是它太大了,无法在不久的将来离开 Coro。我们遇到了竞争条件,其中具有惰性属性的对象在线程出于某种原因放弃的构建器内调用该惰性属性的构建器,然后不同的 coro 线程尝试访问相同的属性,从而触发该属性再次构建。

通常我会保护检查,然后用信号量设置代码,但是 Moose 的检查和设置行为是在 moose 内部,而不是我自己的代码。

如何消除这种竞争条件?

最佳答案

通常,您可以控制从外部对对象或属性的访问。

my $foo_bar_lock = Coro::Semaphore->new();
my $foo = Foo->new();

{
   my $guard = $foo_bar_lock->guard;
   # ... use $foo's bar ...
}

{
   my $guard = $foo_bar_lock->guard;
   # ... use $foo's bar ...
}

但是,它也可以从内部完成。

has bar_lock => (
   reader  => '_get_bar_lock',
   default => sub { Coro::Semaphore->new() },
);

has bar => (
   reader  => '_get_bar',
   writer  => '_set_bar',
   builder => '_build_bar',
   lazy    => 1,
);

sub _build_bar { ... }

sub get_bar { 
   my $self = shift;
   my $guard = $self->_get_bar_lock->guard;
   return $self->_get_bar();
} 

sub set_bar { 
   my $self = shift;
   my $guard = $self->_get_bar_lock->guard;
   return $self->_set_bar(@_);
} 

(如果您更喜欢单个 get-set 访问器而不是单独的 get 和 set 访问器,请使用 accessor 而不是 readerwriter。 )

关于perl - 如何通过 Lazy 属性和 Coro 防止 Moose 中的竞争状况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46029111/

相关文章:

regex - 如何在 Perl 中将正则表达式模式定义为常量?

perl - Perl 的 inet_aton 线程安全吗?

perl - 如何在实现 net-snmp 代理时清除 perl 脚本错误?

perl - Catalyst ("Can' 中的 Moose 访问器使用字符串作为 HASH ref“错误)

perl - 如何使用与主脚本在同一文件中定义的 Moose 类?

perl - 如何在加载的模块中使用 Smart::Comments 而不更改其源?

algorithm - Perl 中发生重大变化时的总计

perl - 为什么在使用 Moose 时覆盖 new 是 "very bad practice"?

Perl 驼鹿 : Attribute only getting set when mentioned in BUILD subroutine

perl - 如何为 Moose 类型特征实现新句柄?