新的C++11机器模型允许多处理器系统可靠地工作.重组指令。
正如Meyers和Alexandrescu指出的那样,“简单”的双重检查锁定模式在C++03中是不安全的。
Singleton* Singleton::instance() {
if (pInstance == 0) { // 1st test
Lock lock;
if (pInstance == 0) { // 2nd test
pInstance = new Singleton;
}
}
return pInstance;
}他们在他们的文章中显示,无论您作为程序员做什么,编译器在C++03中都有太多的自由度:允许以一种可以而不是的方式重新排序指令--请确保只得到一个Singleton实例。
我现在的问题是:
Lock )时,这种单例模式的安全C++11实现现在是什么样的呢?发布于 2011-05-15 15:13:05
如果pInstance是一个常规指针,则代码具有潜在的数据竞争--对指针(或任何内置类型)的操作不能保证是原子的(编辑:或有序的)。
如果pInstance是std::atomic<Singleton*> ,而 Lock在内部使用std::mutex来实现同步(例如,如果Lock实际上是std::lock_guard<std::mutex>),则代码应该是无数据竞争的。
请注意,您需要--显式锁定和原子pInstance --才能实现适当的同步。
发布于 2013-09-05 13:22:17
由于静态变量初始化现在保证为threadsafe,Meyer的单例应该是threadsafe。
Singleton* Singleton::instance() {
static Singleton _instance;
return &_instance;
}现在,您需要解决主要问题:代码中有一个Singleton。
编辑:基于下面的评论:与其他实现相比,这个实现有一个很大的缺点。如果编译器不支持此特性,会发生什么情况?编译器将发出线程不安全的代码,甚至不会发出警告。如果编译器不支持新接口,具有锁的其他解决方案甚至不会编译。这可能是一个很好的理由,不依赖这个特性,即使是在其他事情上,而不是单例。
发布于 2011-05-15 13:44:30
C++11并没有改变实现双重检查锁定的意义。如果你想使双重检查锁定工作,你需要建立适当的记忆屏障/栅栏。
https://stackoverflow.com/questions/6008715
复制相似问题