锁定语句的内存障碍

时间:2010-05-16 16:16:00

标签: c# memory-barriers

我最近读到了有关内存障碍和重新排序的问题,现在我对此感到困惑。

考虑以下情况:

private object _object1 = null;    
private object _object2 = null;
private bool _usingObject1 = false;

private object MyObject
{
    get 
    {
        if (_usingObject1)
        {
            return _object1;
        }
        else
        {
            return _object2;
        }
    }
    set 
    {
        if (_usingObject1)
        {
           _object1 = value;
        }
        else
        {
           _object2 = value;
        }
    }
}

private void Update()
{
    _usingMethod1 = true;
    SomeProperty = FooMethod();
    //..
    _usingMethod1 = false;
}
  1. Update方法;是获取或设置属性之前始终执行的_usingMethod1 = true语句?或者由于重新订购问题我们无法保证?

  2. 我们应该使用volatile之类的

    吗?
    private volatile bool _usingMethod1 = false;
    
  3. 如果我们使用lock;,我们可以保证锁中的每个语句都会按顺序执行:

    private void FooMethod()
    {
        object locker = new object();
        lock (locker)
        {
            x = 1;
            y = a;
            i++;
        }
    }
    

2 个答案:

答案 0 :(得分:28)

记忆障碍的主题非常复杂。它甚至不时让专家绊倒。当我们谈论记忆障碍时,我们确实将两种不同的想法结合起来。

  • 获取围栏:一个记忆障碍,其他读取&在围栏之前,不允许写入
  • 释放栅栏:一种记忆屏障,其他读取&在围栏之后,不允许写入

仅创建两个中的一个的内存屏障有时称为半栅栏。创建两者的内存屏障有时称为全屏

volatile关键字会创建半围栏。易失性字段的读取具有获取语义,而写入具有释放语义。这意味着在读取之前或写入之后不能移动指令。

lock关键字在两个边界(入口和出口)上创建全围栏。这意味着在每个边界之前或之后都不能移动指令。

然而,如果我们只关心一个线程,那么所有这些都没有用。由该线程感知的排序始终保留。事实上,没有基本保证,任何计划都无法正常运作。真正的问题是其他线程如何感知读写。这是你需要关注的地方。

所以回答你的问题:

  1. 从一个线程的角度来看......是的。从另一个主题的角度来看......不。

  2. 这取决于。这可能有用,但我需要更好地了解你想要实现的目标。

  3. 从另一个主题的角度来看......没有。读取和写入可以在锁定边界内自由移动。他们只是无法超越这些界限。这就是为什么其他线程也必须创建内存障碍的原因。

答案 1 :(得分:4)

volatile关键字在这里没有完成任何事情。它有很弱的保证,并不意味着存储障碍。您的代码未显示另一个创建的线程,因此很难猜测是否需要锁定。但是,如果两个线程可以同时执行Update()并使用相同的对象,那么这是一个很难的要求。

请注意,您发布的锁码不会锁定任何内容。每个线程都有自己的“locker”对象实例。你必须使它成为你的类的私有字段,由构造函数或初始化程序创建。因此:

private object locker = new object();

private void Update()
{
    lock (locker)
    {
        _usingMethod1 = true;
        SomeProperty = FooMethod();
        //..
        _usingMethod1 = false;
    }
}

请注意,SomeProperty分配也会有竞争。