Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Infinite loop in release mode

When I run the following code in debug mode, it'll successfully finish and exit. However, if I run the following code in release mode, it'll get stuck in an infinite loop and never finish.

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.");
}

Which optimization is causing it to get stuck in an infinite loop?

like image 660
nivlam Avatar asked May 25 '12 04:05

nivlam


People also ask

How do you exit an endless loop?

You can press Ctrl + C .

What causes an infinite loop?

Usually, an infinite loop results from a programming error - for example, where the conditions for exit are incorrectly written. Intentional uses for infinite loops include programs that are supposed to run continuously, such as product demo s or in programming for embedded system s.

How do you make a for loop run forever?

To make an infinite loop, just use true as your condition. true is always true, so the loop will repeat forever. Warning: Please make sure you have a check that exits your loop, otherwise it will never end.


2 Answers

My guess would be processor caching of the stop variable on the main thread. In debug mode the memory model is stricter because the debugger needs to be able to provide a sensible view of the variable's state across all threads.

Try making a field and marking 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.");
}
like image 61
Chris Shain Avatar answered Sep 19 '22 22:09

Chris Shain


Because it's not thread safe you update the main thread variable stop inside the child thread. It will always be unpredictable. To work with any situation like this, have a look on this article.

The volatile keyword instructs the compiler to generate an acquire-fence on every read from that field, and a release-fence on every write to that field. An acquire-fence prevents other reads/writes from being moved before the fence; a release-fence prevents other reads/writes from being moved after the fence. These “half-fences” are faster than full fences because they give the runtime and hardware more scope for optimization.

like image 27
ABH Avatar answered Sep 20 '22 22:09

ABH