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?
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.
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 TRUEFlag = False
var read2 = Flag;
//read2 is FALSE, but read1 remains TRUEThis is valid in non multithreaded environment too, cause you operating on value type.
If this is not what you're asking for, please clarify.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With