我想在多线程程序中使用单例模式。双重检查锁定方法似乎适合它的效率,但是这种方法是错误的并且不容易正确。
我编写了以下代码,希望它能替代双重检查锁定。它是线程安全单例模式的正确实现吗?
static bool created = false;
static Instance *instance = 0;
Instance *GetInstance() {
if (!created) {
Lock lock; // acquire a lock, parameters are omitted for simplicity
if (!instance) {
instance = new Instance;
} else {
created = true;
}
}
return instance;
}
第一次调用将创建实例。第二次调用会将 created 设置为 true。最后,所有其他调用将返回一个初始化良好的实例。
http://voofie.com/content/192/alternative-to-double-checked-locking-and-the-singleton-pattern/
最佳答案
不,这没有帮助。如果对 created
和 instance
的写入是非原子的,则无法保证这些值对未锁定互斥锁的线程可见。
例如线程 1 调用 getInstance
。 created
为 false
,instance
为 null,因此它锁定互斥量并创建一个新实例。线程 1 再次调用 getInstance
,这次将 created
设置为 true
。线程 2 现在调用 getInstance
。由于处理器内存管理的变幻莫测,它将 created
视为 true
,但不能保证它也将 instance
视为非空,即使它确实存在,也不能保证所指向实例的内存值是一致的。
如果您不使用原子,那么您需要使用互斥锁,并且必须将它们用于对 protected 变量的所有访问。
附加信息:如果您正在使用互斥体,那么编译器和运行时一起工作以确保当一个线程释放互斥体锁而另一个线程获取同一互斥体上的锁时,第二个线程可以看到由首先。这对于非原子访问是不正确的,对于原子访问可能是也可能不是真的,这取决于编译器和运行时为您保证的内存排序约束(使用 C++11 原子,您可以选择排序约束)。
关于c++ - 这是双重检查锁定的有效替代方案吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9060882/