我们真的需要在C#中volatile关键字?

问题描述:

下面是我努力我的工作站上的代码。

Here is the code that I was trying on my workstation.

class Program
{
    public static volatile bool status = true;

    public static void Main()
    {
        Thread FirstStart = new Thread(threadrun);
        FirstStart.Start();

        Thread.Sleep(200);

        Thread thirdstart = new Thread(threadrun2);
        thirdstart.Start();

        Console.ReadLine();

    }

    static void threadrun()
    {
        while (status)
        {
            Console.WriteLine("Waiting..");
        }
    }

    static void threadrun2()
    {
        status = false;
        Console.WriteLine("the bool value is now made FALSE");
    }
}



正如你可以看到我已经解雇了三个线程。然后使用断点跟踪我的线程。我最初的构想是所有三个线程将被同时烧制,但我的断点流量表明,线程的执行流,随后一个接等(等于是输出格式,即顶到螺纹底部执行)。伙计们这是为什么发生?

As you can see I have fired three threads in Main. Then using breakpoints I tracked the threads. My initial conception was all the three threads will be fired simultaneously, but my breakpoint flow showed that the thread-execution-flow followed one after other (and so was the output format i.e. Top to bottom execution of threads). Guys why is that happening ?

此外我试图在不使用声明volatile关键字运行相同的程序,我发现在执行程序没有变化。我怀疑挥发性关键词没有实际的现场使用。 ?难道我走错了地方。

Additionally I tried to run the same program without using the volatile keyword in declaration, and I found no change in program execution. I doubt the volatile keyword is of no practical live use. Am I going wrong somewhere?

好吧,我会尽量解释一个很长的故事尽可能短:

Ok I will try to explain a very long story as short as possible:

1号:试图检查与调试器线程的行为是重复运行多线程程序,并得出结论认为,它工作得很好,因为出100有用测试无故障:错!线程的行为在一个完全不确定的(有些人会说是随机的)的方式,你需要不同的方法,以确保这样的程序将正常运行。

Number 1: Trying to inspect the behavior of threads with the debugger is as useful as repeatedly running a multithreaded program and concluding that it works fine because out of 100 tests none failed: WRONG! Threads behave in a completely nondeterministic (some would say random) way and you need different methods to make sure such a program will run correctly.

2号:使用挥发性一旦你删除它,然后运行在调试模式下的程序,然后切换到发布模式将变得清晰。我认为你将有一个惊喜...什么发生在释放模式是编译器将优化代码(这包括重新排序指令和数值的高速缓存)。现在,如果你的两个线程在不同的处理器核上运行,然后执行被检查的的状态值线程的核心将缓存反复检查它的值来代替。其他线程将设置它,但第一个将永远不会看到的变化:死锁! 挥发性防止这种情况的发生。

Number 2: The use of volatile will become clear once you remove it and then run your program in Debug mode and then switch to Release mode. I think you will have a surprise... What happens in Release mode is that the compiler will optimize code (this includes reordering instructions and caching of values). Now, if your two threads run on different processor cores, then the core executing the thread that is checking for the value of status will cache its value instead of repeatedly checking for it. The other thread will set it but the first one will never see the change: deadlock! volatile prevents this kind of situation from occurring.

在某种意义上,挥发性是万一保护的代码实际上并不(而且很可能不会)因为你认为它会在多线程的情况下运行。

In a sense, volatile is a guard in case the code does not actually (and most likely will not) run as you think it will in a multithreaded scenario.