Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do properties have volatile effect?

In the code below will read1 be always equal to read2, provided property Flag can be changed from other threads? Concern here is that Flag may get inlined.

private bool Flag {get; set;}

public void MultithreadedMethod()
{
    var read1 = Flag;

    /* some more code */

    var read2 = Flag;    
}

UPD: Some other thread may change Flag's value during /* some more code */ execution. In this case read1 should be different from read2. Will it always be the case? Won't inlining turn the property into an non-volatile field that will cause read1 to be equal to read2 despite tha fact Flag was changed between reads?

like image 879
shtriha Avatar asked May 29 '12 09:05

shtriha


3 Answers

No, the property is not volatile.

While I have not been able to obtain a satisfactory demonstration for your initial scenario, this alternative method should prove the statement nicely:

class Program
{
    public bool Flag { get; set; }

    public void VolatilityTest()
    {
        bool work = false;
        while (!Flag)
        {
            work = !work; // fake work simulation
        }
    }

    static void Main(string[] args)
    {
        Program p = new Program();
        var t = new Thread(p.VolatilityTest);
        t.Start();
        Thread.Sleep(1000);
        p.Flag = true;
        t.Join();
    }
}

Building this in Release mode will make the program deadlock, hence proving that Flag does not have volatile behavior (i.e. it gets "optimized" between reads).

Replacing public bool Flag { get; set; } with public volatile bool Flag; will make the program terminate correctly.

like image 75
Tudor Avatar answered Nov 11 '22 13:11

Tudor


Yes it can be changed naturally.

Even in the code provided it's not guranteed that read1 would be equal to read2.

Considering that meanwhile /* some more code */ executed, Flag can be affected by other threads.

EDIT

The equality of read1 and read2 has nothing to do with inlining or not, Flag is a bool, so it's a value type. So

  • var read1 = Flag; //let's say read1 TRUE
  • Flag = False
  • var read2 = Flag; //read2 is FALSE, but read1 remains TRUE

This is valid in non multithreaded environment too, cause you operating on value type.

If this is not what you're asking for, please clarify.

like image 26
Tigran Avatar answered Nov 11 '22 12:11

Tigran


if Flag can be changed from other threads, there is no guarantee that read1 and read2 will be the same. You would have to use a monitor/mutex surrounding your code and also make sure that the Flag setter also respects that mutex.

like image 1
Dirk Trilsbeek Avatar answered Nov 11 '22 14:11

Dirk Trilsbeek