【问题标题】:Writing data with locks, but reading without a lock [duplicate]带锁写入数据,但不带锁读取[重复]
【发布时间】:2020-03-28 01:01:17
【问题描述】:

如果我使用多个线程将数据写入属性,例如: 公共十进制数;

使用 volatile decimal 是否允许我在不使用锁的情况下安全地读取十进制异常?

【问题讨论】:

  • 没有。阅读这些:Part 1Part 2。永远不要使用volatile(除非您在 Microsoft 工作,但是很多 C# 语言设计人员表示他们对 volatile 的语义不够满意而无法使用它)。还有,撕裂。
  • 既然你是用锁写的,为什么不直接用锁来读取呢?
  • This answer 用于标记的重复地址正是您的问题,直接而清晰。
  • @canton7:感谢您的链接。我需要把这些移到我的博客上。

标签: c#


【解决方案1】:

无法将decimal 标记为volatile。你会得到一个编译器错误。原因是这种类型的操作由于其大小不能保证是原子的。

您不能假设无锁读取是安全的。它可能会返回一个部分写入的值,该值可能是无效的,并且绝对不是想要的值。

【讨论】:

  • 哦,好吧,所以即使我可以设置为 volatile 的其他类型仍然不能安全读取?
  • 其他类型应该尽量使用Interlocked类进行读写,没有locks。
  • (请注意,您需要同时使用Interlocked 来读取和 写入——您不能仅将Interlocked 用于写入,而忽略它用于读取)
  • @Andyx:您需要清楚地定义“安全阅读”的含义。您对什么安全属性感兴趣? volatile 只保证极少数的安全属性;它保证了原子性,因为只有原子类型可以被标记为易失性,并且它保证读取不会因某些其他特殊效果而及时向后移动;也就是说,它引入了半栅栏。如果你对栅栏的推理感到不舒服,那么你应该做我所做的,而不是使用volatile。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-04
  • 2011-01-25
相关资源
最近更新 更多