Infinite loop in release mode

前端 未结 4 547
Happy的楠姐
Happy的楠姐 2020-12-15 19:08

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 i

相关标签:
4条回答
  • 2020-12-15 19:50

    Looks like some sort of optimization for value of local variable - changing to a field make it terminate ok (note that volatile or correct locking should be used in actual code):

    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 讨论(0)
  • 2020-12-15 19:58

    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.

    0 讨论(0)
  • 2020-12-15 19:58

    Thread Unsafe code is unpredictable. Main problem is changing one thread variable from another thread. 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 讨论(0)
  • 2020-12-15 20:00

    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.");
    }
    
    0 讨论(0)
提交回复
热议问题