A reproducible example of volatile usage

前端 未结 2 2079
半阙折子戏
半阙折子戏 2020-11-28 14:47

I am look for a reproducible example that can demonstrate how volatile keyword works. I\'m looking for something that works \"wrong\" without variable(s) marked as volatile

2条回答
  •  借酒劲吻你
    2020-11-28 15:18

    You can use this example to demonstrate the different behavior with and without volatile. This example must be compiled using a Release build and ran outside of the debugger1. Experiment by adding and removing the volatile keyword to the stop flag.

    What happens here is that the read of stop in the while loop is reordered so that it occurs before the loop if volatile is omitted. This prevents the thread from ending even after the main thread set the stop flag to true.

    class Program
    {
        static bool stop = false;
    
        public static void Main(string[] args)
        {
            var t = new Thread(() =>
            {
                Console.WriteLine("thread begin");
                bool toggle = false;
                while (!stop)
                {
                    toggle = !toggle;
                }
                Console.WriteLine("thread end");
            });
            t.Start();
            Thread.Sleep(1000);
            stop = true;
            Console.WriteLine("stop = true");
            Console.WriteLine("waiting...");
    
            // The Join call should return almost immediately.
            // With volatile it DOES.
            // Without volatile it does NOT.
            t.Join(); 
        }
    }
    

    It should also be noted that subtle changes to this example can reduce its probability of reproducibility. For example, adding Thread.Sleep (perhaps to simulate thread interleaving) will itself introduce a memory barrier and thus the similar semantics of the volatile keyword. I suspect Console.WriteLine introduces implicit memory barriers or otherwise prevents the jitter from using the instruction reordering operation. Just keep that in mind if you start messing with the example too much.


    1I believe that framework version prior to 2.0 do not include this reordering optimization. That means you should be able to reproduce this behavior with version 2.0 and higher, but not the earlier versions.

提交回复
热议问题