Endless loop in release mode

When I run the following code in debug mode, it will complete successfully and complete. However, if I run the following code in release mode, it will get stuck in an infinite loop and never end.

static void Main(string[] args) { bool stop = false; new Thread(() => { Thread.Sleep(1000); stop = true; Console.WriteLine("Set \"stop\" to true."); }).Start(); Console.WriteLine("Entering loop."); while (!stop) { } Console.WriteLine("Done."); } 

What kind of optimization makes it stuck in an infinite loop?

+19
multithreading c #
May 25 '12 at 4:16
source share
4 answers

My guess would be to cache the variable stop in the main thread. In debug mode, the memory model is more strict, because the debugger should be able to provide a reasonable representation of the state of the variable in all threads.

Try creating a field and mark it as volatile :

 volatile bool stop = false; static void Main(string[] args) { new Thread(() => { Thread.Sleep(1000); stop = true; Console.WriteLine("Set \"stop\" to true."); }).Start(); Console.WriteLine("Entering loop."); while (!stop) { } Console.WriteLine("Done."); } 
+18
May 25 '12 at 4:21
source share

Since it is not thread safe, you are updating the stop main thread variable inside the child thread. It will always be unpredictable. To work with any situation like this, see this article .

The volatile keyword instructs the compiler to generate a guard every time it reads from this field, as well as every record in this field. The fence-fence prevents others from reading / writing out of movement before the fence; the fence prevents the movement of other reads / records after the fence. These midfielders are faster than full fences because they give runtime and hardware more room for optimization.

+11
May 25 '12 at 4:21
source share

Subject Unsafe code is unpredictable. The main problem is changing one stream variable from another stream. Make the variable global or volatile. You can do it by following

 static volatile bool stop = false; static void Main(string[] args) { new Thread(() => { Thread.Sleep(1000); stop = true; Console.WriteLine("Set \"stop\" to true."); }).Start(); Console.WriteLine("Entering loop."); while (!stop) { } Console.WriteLine("Done."); } 
0
May 25 '12 at 4:37
source share

It seems like some kind of optimization for the value of the local variable - changing the field leads to the completion of ok (note that in the real code you should use volatile or proper locking):

 using System; using System.Threading; class Program { static bool stop = false; static void Main(string[] args) { new Thread(() => { Thread.Sleep(1000); stop = true; Console.WriteLine("Set \"stop\" to true."); }).Start(); Console.WriteLine("Entering loop."); while (!stop) { } Console.WriteLine("Done."); } } 
0
May 25 '12 at 4:53
source share



All Articles