c++ - 这是双重检查锁定的有效替代方案吗?

标签 c++ multithreading thread-safety

我想在多线程程序中使用单例模式。双重检查锁定方法似乎适合它的效率,但是这种方法是错误的并且不容易正确。

我编写了以下代码,希望它能替代双重检查锁定。它是线程安全单例模式的正确实现吗?

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/

最佳答案

不,这没有帮助。如果对 createdinstance 的写入是非原子的,则无法保证这些值对未锁定互斥锁的线程可见。

例如线程 1 调用 getInstancecreatedfalseinstance 为 null,因此它锁定互斥量并创建一个新实例。线程 1 再次调用 getInstance,这次将 created 设置为 true。线程 2 现在调用 getInstance。由于处理器内存管理的变幻莫测,它将 created 视为 true,但不能保证它也将 instance 视为非空,即使它确实存在,也不能保证所指向实例的内存值是一致的。

如果您不使用原子,那么您需要使用互斥锁,并且必须将它们用于对 protected 变量的所有访问。

附加信息:如果您正在使用互斥体,那么编译器和运行时一起工作以确保当一个线程释放互斥体锁而另一个线程获取同一互斥体上的锁时,第二个线程可以看到由首先。这对于非原子访问是不正确的,对于原子访问可能是也可能不是真的,这取决于编译器和运行时为您保证的内存排序约束(使用 C++11 原子,您可以选择排序约束)。

关于c++ - 这是双重检查锁定的有效替代方案吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9060882/

相关文章:

c# - 在 C# 中创建线程

multithreading - PyGTK:gobject.idle_add() 和 timeout_add() 与线程

java - 在同一个函数的 synchronized() block 中初始化后,能否在 synchronized() 之外安全地使用 Java 集合?

.net - 有没有人写过线程安全的BindingList <T>?

c++ - Eigen 中填充稀疏矩阵的速度取决于节点数或边数?

c++ - 将静态库添加到C或C++项目的通常方法是什么?

c++ - 多态C++:基本指针字段未使用派生类构造函数提供的值

c++ - 从 C++ 源代码创建类图?

objective-c - 从不同线程访问只读对象的思考

c++ - 处理异常后阻止线程在分离时调用 std::terminate()