0

我在 perl 上使用共享变量和 use threads::shared。我们只能从单个线程修改该变量,所有其他线程只能“读取”该变量。

在“阅读”线程中是否需要锁定

  {
    lock $shared_var;
    if ($shared_var > 0) .... ;
  }

?

在没有锁定的情况下进行简单验证是否安全(在“阅读”线程中!),比如

  if ($shared_var > 0) ....

?

4

2 回答 2

3

在设置或获取标量时,不需要锁定来保持内部完整性。

在您的特定情况下是否需要它取决于读者、其他读者和作者的需求。不锁定几乎没有意义,但您没有提供足够的详细信息让我们确定您的需求。

例如,在编写器更新共享变量后使用旧值可能是不可接受的。对于初学者来说,这可能会导致一个线程仍在使用旧值而另一个线程正在使用新值的情况,如果这两个线程交互,这种情况可能是不可取的。

于 2013-03-26T11:52:02.717 回答
1

这取决于在某个时间点或其他时间点测试条件是否有意义。然而问题在于,在绝大多数情况下,布尔测试意味着其他东西,当你读完表示它代表先前状态的条件时,这些东西可能已经改变了。

想想看。如果这是一个微不足道的测试,那么它就没有什么意义——你必须质疑你为什么要做它。如果这是一个重要的测试,那么它说明了一个可能存在也可能不存在的连贯状态——除非你知道,否则你无法确定lock

很多时候,比如在实时报告中,您并不真正关心数据库提供给您的快照,您只需要一个相对最新的快照。但是,作为其事务逻辑的一部分,它会完整地了解提交之前的情况。我认为您不太可能在代码中找到这一点,其中当前状态就是当前状态——甚至处于临时状态的状态也是确定状态。

我想这可能会有所不同的一次是队列的循环访问。如果一个消费者这次没有得到头条记录,那么他们中的一个将在下一次得到。您可能可以节省一些处理时间,异步访问队列计数器。但在这种情况下,它在仅一次迭代的情况下意义不大

在上述情况下,您只需要在之后放置一些锁定级别的指令,即预期队列实际上可能是空的,即使您的测试表明它有数据。所以,如果它只是一个初步测试,你必须有逻辑将测试视为不可靠,因为它实际上是。

于 2013-03-26T12:08:28.073 回答