【问题标题】:How to prevent race condition in Moose with Lazy attributes and Coro如何使用 Lazy 属性和 Coro 防止 Moose 中的竞争条件
【发布时间】:2018-02-12 05:21:14
【问题描述】:

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

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

我怎样才能消除这种竞争条件?

【问题讨论】:

    标签: perl moose


    【解决方案1】:

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

    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。)

    【讨论】:

    • 你为什么使用scope finalized而不是coro::semaphore的guard方法?
    • 我不知道 Coro::Semaphore 的 guard 方法。固定。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-23
    • 1970-01-01
    • 1970-01-01
    • 2014-05-27
    • 2016-03-21
    • 2016-12-10
    • 1970-01-01
    相关资源
    最近更新 更多