问题描述
我有一个变量用来表示状态.它可以从多个线程中读取和写入.
I have a variable which I am using to represent state. It can be read and written to from multiple threads.
我正在使用 Interlocked.Exchange
和 Interlocked.CompareExchange
来更改它.但是我正在从多个线程中读取它.
I am using Interlocked.Exchange
and Interlocked.CompareExchange
to change it. However I am reading it from multiple threads.
我知道 volatile
可用于确保变量不在本地缓存,而是始终直接从内存中读取.
I know that volatile
can be used to make sure the variable is not cached locally but always reads directly from memory.
但是,如果我将变量设置为 volatile,那么它会生成一个关于使用 volatile 并将 using ref 传递给 Interlocked 方法的警告.
However if I set the variable to volatile then it generates a warning about using volatile and passing using ref to the Interlocked methods.
我想确保每个线程都在读取变量的最新值,而不是某个缓存版本,但我不能使用 volatile.
I want to ensure that each thread is reading the most recent value of the variable and not some cached version, but I can't use volatile.
有一个 Interlocked.Read
但它适用于 64 位类型,在紧凑框架上不可用.它的文档说 32 位类型不需要它,因为它们已经在单个操作中执行.
There is a Interlocked.Read
but it is for 64 bit types and is not available on the compact framework. The documentation for it says that it is not needed for 32 bit types as they are already performed in a single operation.
互联网上有一些声明说,如果您对所有访问都使用互锁方法,则不需要 volatile.但是,您无法使用 Interlocked 方法读取 32 位变量,因此您无法使用 Interlocked 方法进行所有访问.
There are statements made across the internet that you don't need volatile if you are using the Interlocked methods for all your access. However you can't read a 32 bit variable using the Interlocked methods, so there is no way you can use Interlocked methods for all your access.
有没有什么方法可以在不使用锁的情况下完成我的变量的线程安全读写?
Is there some way to accomplish the thread safe read and write of my variable without using lock?
推荐答案
您可以放心地在使用 Interlocked.Xxx
函数时忽略该警告(请参阅 this question),因为它们总是执行易失性操作.所以 volatile
变量对于共享状态来说是完全可以的.如果您想不惜一切代价摆脱警告,您实际上可以使用 Interlocked.CompareExchange (ref counter, 0, 0)
进行互锁读取.
You can safely disregard that warning when you're using Interlocked.Xxx
functions (see this question), because they always do volatile operations. So a volatile
variable is perfectly OK for shared state. If you want to get rid of the warning at all costs, you actually can do an interlocked read with Interlocked.CompareExchange (ref counter, 0, 0)
.
实际上,如果您要直接写入状态变量,则需要volatile
(即不使用Interlocked.Xxx
).如 jerryjvl 所述,读取使用互锁(或易失性)操作更新的变量将使用最新的值.
Actually, you need volatile
on your state variable only if you are going to write to it directly (i.e. not using Interlocked.Xxx
). As jerryjvl mentioned, reads of a variable updated with an interlocked (or volatile) operation will use the most recent value.
这篇关于互锁且易变的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!