Could a shared memory be updated in some thread while its value is still not visible to the main thread?
I was reading this article about volatile fields in C#.
using System;
using System.Threading;
class Test
{
public static int result;
public static volatile bool finished;
static void Thread2() {
result = 143;
finished = true;
}
static void Main() {
finished = false;
// Run Thread2() in a new thread
new Thread(new ThreadStart(Thread2)).Start();
// Wait for Thread2 to signal that it has a r开发者_开发技巧esult by setting
// finished to true.
for (;;) {
if (finished) {
Console.WriteLine("result = {0}", result);
return;
}
}
}
}
As you can see, there's a loop in the main thread that waits for the volatile flag to be set in order to print 'result', which is assigned to 143 before the flag is set. It says in the explanation that if the flag was not declared as volatie then
it would be permissible for the store to result to be visible to the main thread after the store to finished
Did I miss something here? Even if it was not volatile, how come the program will ever printout 0.
Volatile prevents (among other things) re-ordering, so without volatile it could as an edge condition conceivably (on some hardware) write them in a different order, allowing the flag to be true even though result is 0 - for a tiny fraction of time. A much more likely scenario, though, is that without volatile the hot loop caches the flag in a register and never exits even though it has been changed.
In reality, this is not a good way to handle concurrency, and in particular a hot loop like that is really actively harmful. In most common cases, a lock or a wait-handle of some kind would be preferred. Or a Task would be ideal if you are up to date in your .NET versions.
精彩评论