相关疑难解决方法(0)

双重检查锁定模式

C++和Double-Checked Locking的Perils中,有一些persudo代码可以正确地实现模式,这是作者建议的.见下文,

Singleton* Singleton::instance () {
    Singleton* tmp = pInstance;
    ... // insert memory barrier (1)
    if (tmp == 0) {
        Lock lock;
        tmp = pInstance;
        if (tmp == 0) {
            tmp = new Singleton;
            ... // insert memory barrier (2)
            pInstance = tmp;
        }
    }
    return tmp;
}
Run Code Online (Sandbox Code Playgroud)

我只是想知道第一个内存屏障是否可以在return语句的正上方移动?

编辑:另一个问题:在链接文章中,引用vidstige

从技术上讲,您不需要完全双向障碍.第一道屏障必须防止Singleton构造的向下迁移(通过另一个线程); 第二个障碍必须阻止pInstance初始化的向上迁移.这些被称为"获取"和"释放"操作,并且可以产生比硬件(例如Itainum)上的完全障碍更好的性能.

它说第二个障碍不需要是双向的,那么如何防止pInstance的赋值在该障碍之前被移动?即使第一个障碍可以阻止向上迁移,但另一个线程仍然有机会看到未初始化的成员.

编辑:我想我几乎明白第一道屏障的目的.正如sonicoder所指出的,当if返回true时,分支预测可能导致tmp为NULL.为了避免这个问题,必须有一个获取障碍,以防止在读取if之前读取tmp.

第一道屏障与第二道屏障配对以实现同步关系,因此它可以向下移动.

编辑:对于那些对这个问题感兴趣的人,我强烈建议阅读memory-barriers.txt.

c++ multithreading double-checked-locking

12
推荐指数
1
解决办法
2991
查看次数