在C++和双重检查锁定的危险中,作者建议使用正确的模式来实现伪代码。请参见下面的内容:
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;
}
我想知道第一个内存屏障是否可以移动到return语句的上方?
编辑:另一个问题:在链接的文章中,如vidstige所引用,
“技术上来说,你不需要完整的双向屏障。第一个屏障必须防止Singleton的构造(由另一个线程)向下迁移;第二个屏障必须防止pInstance的初始化向上迁移。这些被称为“获取”和“释放”操作,在硬件上(如Itainum)可能比全屏障具有更好的性能。”
它说第二个屏障不需要是双向的,那么它如何防止对pInstance的赋值在该屏障之前被移动?尽管第一个屏障可以防止向上迁移,但另一个线程仍然有机会看到未初始化的成员。
编辑:
编辑:对于那些对这个问题感兴趣的人,我强烈推荐阅读memory-barriers.txt。
return
之前放置一个屏障就可以了。所以问题是,是否存在其他危险,这意味着屏障的特定位置很重要? - Steve Jessop