这个c#类的变量需要是volatile的吗?

15 浏览
0 Comments

这个c#类的变量需要是volatile的吗?

在下面的C#代码中,RunHelper()只从Run()中调用。由于编译器知道这一点,它是否会优化它,以便将if(terminate)替换为if(false)

class Dummy
{
    private bool terminate;
    public Dummy() 
    {
        terminate = false;
    }
    public void KillDummy() // 从另一个线程调用
    {
        terminate = true;
    }
    public void Run()
    {
        terminate = false;
        RunHelper();
    }
    private void RunHelper() // 只从Run函数中调用
    {
        if(terminate)
        {
            Console.WriteLine("Exiting");
        }
    }
}

0
0 Comments

这篇文章讨论了一个关于C#类变量是否需要使用volatile关键字的问题,并提供了解决方法。

文章首先提到,在从C#编译到IL时,对RunHelper的检查优化不会发生。然而,JIT(从IL编译到机器代码的过程)可能会将RunHelper内联到Run中,从而避免调用,造成你担心的优化问题。即使使用反射也无法解决这个问题,因为反射只能看到IL代码,而无法查看机器代码。

然后,文章讨论了线程可见性的问题。如果系统经常使用这段代码,它会将terminate变量保存在缓存中,而其他线程可能不会意识到对它所做的更改。因此,需要使用volatile关键字或类似的解决方案来解决这个问题。

文章还提到了volatile关键字的其他注意事项,但这些注意事项似乎不会影响你的代码。例如,重排序不仅发生在编译器中,CPU也可以进行重排序。使用volatile关键字可以对重排序进行约束。然而,写操作仍然可以在读操作之后被移动,需要使用完整的内存屏障来解决这个问题。如果遇到ABA问题,需要使用Interlocked类来解决,这意味着无法使用volatile关键字,而必须只使用Interlocked或volatile操作来处理变量。此外,还提到了一些相关链接供进一步参考。

总之,文章解释了为什么在某些情况下需要使用volatile关键字来确保线程可见性,并提供了其他解决方案来解决与volatile相关的其他问题。

0