我有我使用表示状态的变量。 它可以读取并从多个线程写入。
我使用Interlocked.Exchange
和Interlocked.CompareExchange
去改变它。 但是我从多个线程读取它。
我知道, volatile
可用于确保变量不是本地缓存,但总是直接从内存中读取。
然而,如果我的变量设置为挥发性然后它产生一个关于使用易失性和使用REF到互锁方法传递警告。
我想确保每个线程读取最近的变量,而不是一些缓存版本的价值,但我不能使用挥发。
有一个Interlocked.Read
但它是64种类型和不适在紧凑的框架。 它的文件说,它不需要32种类型的,因为它们是在一个单一的操作已经执行。
有跨越,如果你正在使用的所有接入互锁方法不需要挥发性网上发了言。 但是,您无法读取使用互锁方法32位的变量,所以也没有办法,你可以使用所有的接入Interlocked方法。
是否有某种方式来完成我的变量的线程安全读写,而无需使用锁?
当你使用,你可以放心地忽略该警告Interlocked.Xxx
功能(见这个问题 ),因为他们总是这样挥发性操作。 所以volatile
变量是共享状态完全确定。 如果你想不惜一切代价摆脱的警告,你其实可以做一个互锁读取Interlocked.CompareExchange (ref counter, 0, 0)
编辑:其实,你需要volatile
你的状态变量只有当你要直接写入到它(即不使用Interlocked.Xxx
)。 如jerryjvl提到 ,读出与一个互锁(或挥发性的)操作所更新的可变的将使用最新的值。
互锁操作和挥发是不是真的应该在同一时间使用。 你会得到一个警告的原因是因为它(几乎?)总是表示你误会你在做什么。
囫囵吞枣,并转述:
volatile
表示需要从内存中重新读取,因为可能有其他线程更新变量每一个读操作。 当应用被你正在运行的架构原子写入可以读取一个字段/,这应该是所有你需要做的,除非你正在使用长/ ULONG,大多数其他类型的可读取/写入原子。
当现场没有标记挥发,可以使用Interlocked
操作作出类似的保证,因为它会导致缓存被刷新,以便更新将是所有其它处理器可见......这有你把负荷的优点在更新,而不是读。
这两个办法的执行最好取决于究竟你在做什么。 而这个解释是毛过于简单。 但它应该是从这个清楚,在同一时间做这两个是没有意义的。