互锁和挥发性(Interlocked and volatile)

2019-06-26 21:13发布

我有我使用表示状态的变量。 它可以读取并从多个线程写入。

我使用Interlocked.ExchangeInterlocked.CompareExchange去改变它。 但是我从多个线程读取它。

我知道, volatile可用于确保变量不是本地缓存,但总是直接从内存中读取。

然而,如果我的变量设置为挥发性然后它产生一个关于使用易失性和使用REF到互锁方法传递警告。

我想确保每个线程读取最近的变量,而不是一些缓存版本的价值,但我不能使用挥发。

有一个Interlocked.Read但它是64种类型和不适在紧凑的框架。 它的文件说,它不需要32种类型的,因为它们是在一个单一的操作已经执行。

有跨越,如果你正在使用的所有接入互锁方法不需要挥发性网上发了言。 但是,您无法读取使用互锁方法32位的变量,所以也没有办法,你可以使用所有的接入Interlocked方法。

是否有某种方式来完成我的变量的线程安全读写,而无需使用锁?

Answer 1:

当你使用,你可以放心地忽略该警告Interlocked.Xxx功能(见这个问题 ),因为他们总是这样挥发性操作。 所以volatile变量是共享状态完全确定。 如果你想不惜一切代价摆脱的警告,你其实可以做一个互锁读取Interlocked.CompareExchange (ref counter, 0, 0)

编辑:其实,你需要volatile你的状态变量只有当你要直接写入到它(即不使用Interlocked.Xxx )。 如jerryjvl提到 ,读出与一个互锁(或挥发性的)操作所更新的可变的将使用最新的值。



Answer 2:

互锁操作和挥发是不是真的应该在同一时间使用。 你会得到一个警告的原因是因为它(几乎?)总是表示你误会你在做什么。

囫囵吞枣,并转述:
volatile表示需要从内存中重新读取,因为可能有其他线程更新变量每一个读操作。 当应用被你正在运行的架构原子写入可以读取一个字段/,这应该是所有你需要做的,除非你正在使用长/ ULONG,大多数其他类型的可读取/写入原子。

当现场没有标记挥发,可以使用Interlocked操作作出类似的保证,因为它会导致缓存被刷新,以便更新将是所有其它处理器可见......这有你把负荷的优点在更新,而不是读。

这两个办法的执行最好取决于究竟你在做什么。 而这个解释是毛过于简单。 但它应该是从这个清楚,在同一时间做这两个是没有意义的。



文章来源: Interlocked and volatile
标签: c# .net mono