【问题标题】:Is it required to lock shared variables in perl for read access?是否需要在 perl 中锁定共享变量以进行读取访问?
【发布时间】:2013-03-26 21:21:07
【问题描述】:

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

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

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

?

不加锁(在“阅读”线程中!)进行简单验证不安全吗,比如

  if ($shared_var > 0) ....

?

【问题讨论】:

    标签: multithreading perl locking


    【解决方案1】:

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

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

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

    【讨论】:

    • 'writer' 线程每 5 分钟从数据库中读取一次配置,并将该配置写入共享哈希 %config;所有其他(读取)线程仅访问该值,例如 sleep($config{'sleep-time'});
    • 这并不能真正告诉我们读者在使用它时是否接受值的变化。例如,如果一个线程使用旧值而另一个线程使用新值,是否可以?这是很少能接受的。但如果它在这里,您可能不需要任何锁定。
    • 'reading' 线程没有修改共享变量(来自 hash %config 的值)。他们只是从中“获取”价值。
    • 我知道。我从来没有说过暗示他们做了什么?! (注意:我在您之前的评论中添加了您的评论。)
    • 你不会得到垃圾。不需要锁定来保持 set 和 fetch 的内部完整性。
    【解决方案2】:

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-31
      • 1970-01-01
      • 2011-08-12
      • 1970-01-01
      • 2011-09-06
      • 2021-09-28
      相关资源
      最近更新 更多