I'm studying c# threading following famous 'C# in a Nutshell' and during investigation of Thread.MemoryBarrier() phenomena, I was scared to death when I stumbled upon Brian's example on Why we need Thread.MemoryBarrier()? .
I'm having i-7 8700K processor and 4.6.1 .NET and I managed to reproduce the problem (program never ends) even with following changes in program:
class Program
{
static bool stop = false;
public static void Main(string[] args)
{
var t = new Thread(() =>
{
Console.WriteLine($"Thread begin");
bool toggle = false;
//while (true)
while (!stop)
{
if (stop)
{
break;
}
toggle = !toggle;
}
Console.WriteLine($"Thread end");
});
t.Start();
Thread.Sleep(1000);
stop = true;
Console.WriteLine($"Stop flag set. Waiting for thread to end...");
t.Join();
Console.ReadKey();
}
}
So, even with "if (stop)" check, problem reproduces and I understand why. When I place "Thread.MemoryBarrier()" before that check problem doesn't reproduce (at least I failed to reproduce it) and I understand why. But what I don't understand is why problem is not reproducing anymore when I change while condition and put "while (true)" instead of "while (!stop)"? Does it have something to do with special treatment of "while (true)" statement?
why problem is not reproducing anymore when I change while condition and put "while (true)" instead of "while (!stop)"?
The behavior depends on several factors like: hardware, operating system, runtime environment... For example, on my machine the problem is not reproduced even with your original code with while (!stop)
. And I believe, the problem can be reproduced with while (true)
on another environment.
Eric Lippert and Jon Skeet state that we don't need to use such low-level techniques like Thread.MemoryBarrier
unless we are real experts in that area ( link#1 and link#2 ). Probably, you should consider to use volatile
keyword with stop
declaration which expresses your intention more explicitly and lets you not to use Thread.MemoryBarrier
. Or even consider use of Task
with CancellationToken
to have ability to cancel Task
.
Looking to your username maybe it worth to note that Eric Lippert and Jon Skeet regarding .net
are like Gandalf regarding magic
Update
Read Eric Lippert's comments below. Don't use volatile
as well as Thread.MemoryBarrier
until you really need it.
There is nothing special about while (true)
.
Your detailed answer is described here: https://msdn.microsoft.com/en-us/magazine/jj863136.aspx
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.