Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interlocked and volatile

Tags:

c#

.net

mono

I have a variable which I am using to represent state. It can be read and written to from multiple threads.

I am using Interlocked.Exchange and Interlocked.CompareExchange to change it. However I am reading it from multiple threads.

I know that volatile can be used to make sure the variable is not cached locally but always reads directly from memory.

However if I set the variable to volatile then it generates a warning about using volatile and passing using ref to the Interlocked methods.

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.

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.

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?

like image 321
trampster Avatar asked Jul 27 '09 05:07

trampster


People also ask

What is interlocked exchange?

Interlock. Exchange returns the original value while performing an atomic operation. The whole point is to provide a locking mechanism. So it is actually two operations: read original value and set new value. Those two together are not atomic.

What is interlocked increment?

Increments a specified variable and stores the result, as an atomic operation. Increment(Int64) Increments a specified variable and stores the result, as an atomic operation.

What is volatile C#?

The volatile keyword indicates that a field might be modified by multiple threads that are executing at the same time. The compiler, the runtime system, and even hardware may rearrange reads and writes to memory locations for performance reasons.


1 Answers

Interlocked operations and volatile are not really supposed to be used at the same time. The reason you get a warning is because it (almost?) always indicates you have misunderstood what you are doing.

Over-simplifying and paraphrasing:
volatile indicates that every read operation needs to re-read from memory because there might be other threads updating the variable. When applied to a field that can be read/written atomically by the architecture you are running on, this should be all you need to do unless you are using long/ulong, most other types can be read/written atomically.

When a field is not marked volatile, you can use Interlocked operations to make a similar guarantee, because it causes the cache to be flushed so that the update will be visible to all other processors... this has the benefit that you put the overhead on the update rather than the read.

Which of these two approaches performs best depends on what exactly you are doing. And this explanation is a gross over-simplification. But it should be clear from this that doing both at the same time is pointless.

like image 183
jerryjvl Avatar answered Sep 21 '22 21:09

jerryjvl