I understand that a thread can cache a value and ignore changes made on another thread, but I'm wondering about a variation of this. Is it possible for a thread to change a cached value, which then never leaves its cache and so is never visible to other threads?
For example, could this code print "Flag is true" because thread a
never sees the change that thread b
makes to flag
? (I can't make it do so, but I can't prove that it, or some variation of it, wouldn't.)
var flag = true;
var a = new Thread(() => {
Thread.Sleep(200);
Console.WriteLine($"Flag is {flag}");
});
var b = new Thread(() => {
flag = false;
while (true) {
// Do something to avoid a memory barrier
}
});
a.Start();
b.Start();
a.Join();
I can imagine that on thread b
flag
could be cached in a CPU register where it is then set to false
, and when b
enters the while
loop it never gets the chance to (or never cares to) write the value of flag
back to memory, hence a
always sees flag
as true.
From the memory barrier generators listed in this answer this seems, to me, to be possible in theory. Am I correct? I haven't been able to demonstrate it in practice. Can anyone come up with a example that does?