Are variables assigned from one thread "thread-safe" when read from another thread if an EventWaitHandel is used?

StackOverflow https://stackoverflow.com/questions/21929644

Question

If I create a variable on one thread then block using a ManualResetEvent's WaitOne() method until another thread assigns a value to the same variable and signals the EventWaitHandel. When I come to read the variable on the first thread am I guaranteed to always get the value just assigned by the other thread?

(I fear I could not get a value from a CPU cache because of some optimisation as I have not used any memory barriers as far as I know).

e.g.

var str = "multi-threading is hard!";
var mre = new ManualResetEvent(false);
Task.Factory.StartNew(() => 
    {
        str = Console.ReadLine();
        mre.Set();
    ));
mre.WaitOne();
Console.WriteLine(str);
Was it helpful?

Solution

Those instructions will not be reordered, which means that, on the producing thread, the field assignment will always occur before the handle is signaled, and, on the consuming thread, the field will always be read after the handle is signaled.

If any of these two pairs of instructions could be re-ordered (e.g., if the second thread could read the field before the handle was signaled), then you would not see the correct value.

WaitOne() introduces an implicit memory barrier, giving you the acquire-release semantics you need.

Brian Gideon and Hans Passant put together a nice list of several classes in the .NET framework that introduce implicit memory barriers: Memory barrier generators

More info: Acquire and release semantics / Acquire and release fences

OTHER TIPS

Your variable is a captured variable, i.e. the compiler turns this local variable into a field of a compiler-generated class, because you are using it in a lambda expression. Afaik, these compiler generated fields are not marked volatile, so they could be cached.

EDIT: Indeed, the field is not volatile.

You could definitely prevent caching by writing your own class so that the compiler does not have to create one. However, this of course hampers the conciseness of your code.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top