【问题标题】:Handling concurrent reads?处理并发读取?
【发布时间】:2014-03-15 16:07:30
【问题描述】:

我是并发编程的新手,我想到了一个特定的情况,我想提供一些意见。如果我有一个变量,我将从多个线程访问但只是为了读取值(它不是常量的唯一原因是因为我需要在运行时设置它),我是否需要一个互斥锁?或者您是否只需要担心还有写入共享资源时的竞争条件?

【问题讨论】:

  • 我想说你应该总是担心比赛条件,但这不是很有帮助。相反,我想知道:您是在启动线程之前还是之后“在运行时设置”?
  • Eric Lippert 的相关、及时的博文:Can I skip the lock when reading an integer? 当然有细微差别,但 TLDR:使用锁;未来的维护者会感谢你没有比赛中的神秘错误,而不是无限小的时间节省。

标签: multithreading concurrency


【解决方案1】:

如果您在启动线程之前设置值,则不需要互斥体。 如果您在启动线程之后设置值,则需要一个互斥锁来确保所有线程读取相同的值。

【讨论】:

  • 谢谢,这正是我想知道的。但是,根据其他一些回复,我认为我仍然会使用互斥锁,以避免将来出现任何混乱
【解决方案2】:

从逻辑上讲,如果您只是读取共享数据,那么您可能不需要使用互斥锁。但是,对于大型程序,您必须使用它以避免混淆。

【讨论】:

  • 如果只在多个线程启动后读取该值,则不需要任何同步。程序有多“大”根本没有任何区别。
  • 它确实有所作为。 :)
【解决方案3】:

这取决于您所谈论的语言和机器架构以及“读取变量”在该语言中的含义。当“读取变量”转换为仅在机器级别从内存读取时,并发读取本身通常是安全的。当然,您需要确保程序中的任何其他内容都不会转化为写入相同的内存区域。

许多主流语言(Java、C#、C、C++)对您的程序如何转换为内存访问仅提供非常弱的保证。同时,您获得的保证往往采用非常复杂的规则形式,例如,关于哪些语句序列可以在何时重新排序。为避免引入真正难以发现的错误,通常最好要求您需要的同步属性以尽可能不微妙和具体的形式,即使用互斥锁。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-21
    • 2012-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-24
    • 1970-01-01
    相关资源
    最近更新 更多