Code example proven to fail w/o volatile

前端 未结 2 605
轻奢々
轻奢々 2021-01-15 13:03

Below is a C# code example which is a verbatim translation of a broken Java code (which has proven to break (i. e. the 2nd thread may fail to observe the change of sha

相关标签:
2条回答
  • 2021-01-15 13:36

    This should get stuck in an infinite loop (I can't test it right now)

    public class Test
    {
      private bool loop = true;
    
      public static void Main()
      {
        Test test = new Test();
        Thread thread = new Thread(DoStuff);
        thread.Start(test);
    
        Thread.Sleep(1000);
    
        test.loop = false;
        Console.WriteLine("loop is now false");
      }
    
      private static void DoStuff(object o) {
        Test test = (Test)o;
        Console.WriteLine("Entering loop");
        while (test.loop) {
    
        }
        Console.WriteLine("Exited loop");
      }
    

    }

    0 讨论(0)
  • 2021-01-15 13:44

    Try running the RELEASE build of the following program (do NOT run it from the debugger otherwise the demonstration won't work - so run the release build via "Debug | Start without debugging"):

    using System;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace Demo
    {
        internal class Program
        {
            private void run()
            {
                Task.Factory.StartNew(resetFlagAfter1s);
                int x = 0;
    
                while (flag)
                    ++x;
    
                Console.WriteLine("Done");
            }
    
            private void resetFlagAfter1s()
            {
                Thread.Sleep(1000);
                flag = false;
            }
    
            private volatile bool flag = true;
    
            private static void Main()
            {
                new Program().run();
            }
        }
    }
    

    The program will terminate after a second.

    Now remove the volatile from the line

    private volatile bool flag = true; // <--- Remove volatile from this
    

    After doing so, the program will now never terminate. (Tested on Windows 8 x64, .Net 4.5)

    Please note, however, that in some cases it is more appropriate to use Thread.MemoryBarrier() rather than declaring the variable volatile, i.e.:

    while (flag)
    {
        Thread.MemoryBarrier();
        ++x;
    }
    

    For more information, see http://blogs.msdn.com/b/brada/archive/2004/05/12/130935.aspx

    0 讨论(0)
提交回复
热议问题