参考分配和阅读原子操作?

rav*_*ven 14 .net c# multithreading visual-studio-2010

我发现了几个关于同一主题的问题,但与一般变量(值和引用类型)有关.这个问题的接受答案是:

CLI规范第12.6.6节的分区I指出:"符合要求的CLI应保证当对位置的所有写入访问的大小相同时,对不大于本机字大小的正确对齐的内存位置的读写访问权限是原子的. ".

引用变量(即类)是指针,等于本机字大小,但我有几个疑问:

参考是否保证在正确对齐的内存位置?

我不明白最后一部分.这是什么意思?"......当对一个位置的所有写访问都是相同的大小时."

简而言之,obj2保证在以下代码的循环的每次迭代中都有效吗?

class MyClass
{
    private OtherClass m_Object;

    void Thread1()
    {
        while(true)
        {
            OtherClass obj1 = new OtherClass();
            m_Object = obj1;
        }
    }

    void Thread2()
    {
        while (true)
        {
            OtherClass obj2 = m_Object;
            // Is obj2 guaranteed to be valid?
            obj2.Check();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Luk*_*keH 11

是的,保证一切都正确对齐,除非你故意不采取措辞错位,这意味着参考分配/读取保证是原子的.

CLI规范的第12.6.6节继续说:

除非使用显式布局控制(请参阅分区II(控制实例布局))来更改默认行为,否则不应大于自然字大小(a的大小native int)的数据元素 .对象引用应被视为存储在本机字大小中.

在规范的第12.6.2节中还有关于对齐等的更多细节.

请注意,在您的示例代码中,读取线程2保证是原子的,但不能保证实际看到线程1所做的任何更改:没有强制执行内存障碍或波动性,每个线程都可以使用自己的"视图" m_Object字段没有看到其他线程所做的更改.

因此,例如,线程1可以将(原子)写入其自己的视图中m_Object,但数据实际上只保存在寄存器或CPU高速缓存中,并且从未进入主存储器.类似地,线程2也可以进行(原子)读取m_Object,但实际上是从寄存器或CPU缓存而不是主存储器读取.