Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does lock section always guarantee thread safety?

I'm trying to understand thread-safe access to fields. For this, i implemented some test sample:

class Program
{   
    public static void Main()
    {
        Foo test = new Foo();
        bool temp;

        new Thread(() => { test.Loop = false; }).Start();

        do
        {
            temp = test.Loop;
        }
        while (temp == true);
    }
}

class Foo
{
    public bool Loop = true;
}

As expected, sometimes it doesn't terminate. I know that this issue can be solved either with volatile keyword or with lock. I consider that i'm not author of class Foo, so i can't make field volatile. I tried using lock:

public static void Main()
{
    Foo test = new Foo();
    object locker = new Object();
    bool temp;

    new Thread(() => { test.Loop = false; }).Start();

    do
    {
        lock (locker)
        {
            temp = test.Loop;
        }
    }
    while (temp == true);
}

this seems to solve the issue. Just to be sure i moved the cycle inside the lock block:

lock(locker)
{
    do
    {
        temp = test.Loop;
    }
    while (temp == true);
}

and... the program does not terminates anymore.

It is totally confusing me. Doesn't lock provides thread-safe access? If not, how to access non-volatile fields safely? I could use VolatileRead(), but it is not suitable for any case, like not primitive type or properties. I considered that Monitor.Enter does the job, Am i right? I don't understand how could it work.

like image 656
shameleo Avatar asked Oct 28 '25 16:10

shameleo


1 Answers

This piece of code:

do
{
    lock (locker)
    {
        temp = test.Loop;
    }
}
while (temp == true);

works because of a side-effect of lock: it causes a 'memory-fence'. The actual locking is irrelevant here. Equivalent code:

do
{
   Thread.MemoryBarrier();   
   temp = test.Loop;       
}
while (temp == true);

And the issue you're trying to solve here is not exactly thread-safety, it is about caching of the variable (stale data).

like image 153
Henk Holterman Avatar answered Oct 31 '25 06:10

Henk Holterman