Search code examples
c#multithreading.net-4.0event-wait-handle

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


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);

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