gpt4 book ai didi

c++ - 对此(希望)100% 安全的双重检查锁定替代单例的任何评论

转载 作者:行者123 更新时间:2023-11-30 00:42:21 33 4
gpt4 key购买 nike

正如 Scott Meyers 和 Andrei Alexandrescu 在 this 中概述的那样文章 简单尝试实现双重检查锁定实现在 C++ 中特别是不安全的,并且通常在不使用内存屏障的多处理器系统上是不安全的。

我对此进行了一些思考,并得出了一个解决方案,它可以避免使用内存屏障,而且在 C++ 中也应该 100% 安全地工作。诀窍是存储指向实例线程局部指针的拷贝,因此每个线程都必须在第一次访问单例时获取锁。

这是一个小示例代码(未检查语法;我使用 pthread 但可以使用所有其他线程库):

class Foo
{
private:
Helper *helper;
pthread_key_t localHelper;
pthread_mutex_t mutex;
public:
Foo()
: helper(NULL)
{
pthread_key_create(&localHelper, NULL);
pthread_mutex_init(&mutex);
}
~Foo()
{
pthread_key_delete(&localHelper);
pthread_mutex_destroy(&mutex);
}
Helper *getHelper()
{
Helper *res = pthread_getspecific(localHelper);
if (res == NULL)
{
pthread_mutex_lock(&mutex);
if (helper == NULL)
{
helper = new Helper();
}
res = helper;
pthread_mutex_unlock(&mutex);
pthread_setspecific(localHelper, res);
}
return res;
}
};

你有什么意见/意见?

您是否发现想法或实现中存在任何缺陷?

编辑:

Helper 是单例对象的类型(我知道这个名字不是赌注……我是从维基百科关于 DCLP 的文章中的 Java 示例中获取的)。Foo 是单例容器。

编辑 2:

因为Foo不是静态类以及它的用法好像有点误会,这里举个用法的例子:

static Foo foo;

.
.
.

foo.getHelper()->doSomething();

.
.
.

Foo 的成员不是静态的原因很简单,因为我能够在构造函数/析构函数中创建/销毁互斥锁​​和 TLS。如果使用 C++ mutex/TLS 类的 RAII 版本,Foo 可以轻松切换为静态。

最佳答案

你好像在打电话:

pthread_mutex_init(&mutex);

...在 Helper() 构造函数中。但是该构造函数本身在使用互斥锁的函数getHelper()(我认为应该是静态的)中被调用。所以互斥量似乎被初始化了两次或根本没有被初始化。

我必须说,我发现代码非常困惑。双重检查锁定并不那么复杂。你为什么不重新开始,这次创建一个 Mutex 类,它进行初始化,并使用 RAI 释放底层 pthread 互斥体?然后使用这个 Mutex 类来实现您的锁定。

关于c++ - 对此(希望)100% 安全的双重检查锁定替代单例的任何评论,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1251167/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com