With all previously discussed caveats about using "volatile" (vs full barriers/interlock*/lock) in mind, there are cases where "volatile" fits the bill. One such example is given in (the footnote of) the accepted answer to Volatile vs. Interlocked vs. lock.
As volatile doesn't prevent these kind of multithreading issues, what's it for? A good example is say you have 2 threads, one which always writes to a variable (say queueLength), and one which always reads from that same variable.
If queueLength is not volatile, thread A may write 5 times, but thread B may see those writes as being delayed (or even potentially in the wrong order).
A solution would be to lock, but you could also in this situation use volatile. This would ensure that thread B will always see the most up-to-date thing that thread A has written. Note however that this logic only works if you have writers who never read, and readers who never write, and if the thing you're writing is an atomic value.
As a variation to that scenario, suppose there is one variable of atomic type, and two threads A and B that each check for and assign mutually different values to the variable. In the simplest case, say that the variable is "volatile bool Do;". Thread A runs a loop that checks Do and, if false, sets it to true. Thread B runs its own loop which checks Do and, if true, sets it to false.
Is this scenario thread-safe in all senses of "safe"?
For an example, below is a (minimal, silly, unconscionable ;-)) code mockup.
volatile static bool Do;
static void ThdA()
{
for(System.Random Rnd = new System.Random();;)
{
if((Rnd.Next() % 10010101) == 0)
{
while(Do); // wait for B to complete
Do = true; // signal B to do something
}
}
}
static void ThdB()
{
for(;;)
{
if(Do)
{
System.Console.Write("doing something\n");
Do = false; // signal A that B done
}
}
}
[ EDIT ] Following some of the comments, I should clarify that my question is as much about saving half a fence in a very special case as it is about verifying my understanding of "volatile" semantics in this particular case. I am not suggesting any new/generic approach, and I am well aware of the ins and (mostly) outs of volatiles in general, as discussed elsewhere (http://blogs.msdn.com/b/ericlippert/archive/2011/06/16/atomicity-volatility-and-immutability-are-different-part-three.aspx, https://msdn.microsoft.com/en-us/magazine/jj883956.aspx, https: //software.intel.com/en-us/blogs/2007/11/30/volatile-almost-useless-for-multi-threaded-programming/ etc).
The question is strictly whether "volatile" is sufficient in the very narrow case described here. The obvious expectations of "safety" are:
- the program never deadlocks;
- neither thread reads stale values (for the code mockup, this translates to each "Do = true" in ThdA having a matching "Do = false" in ThdB).