C++ c++;:这是我的singleton threadsafe的getInstance()方法吗?
我目前正在尝试使用boost::mutex编写线程安全的单例(至少在构造和销毁方面)。我听说boost互斥不能静态初始化(很抱歉,我丢失了我读到它的链接),所以为了解决这个问题,我尝试了以下方法,如果threadsafety for construction and Destroyment是:C++ c++;:这是我的singleton threadsafe的getInstance()方法吗?,c++,boost,singleton,thread-safety,C++,Boost,Singleton,Thread Safety,我目前正在尝试使用boost::mutex编写线程安全的单例(至少在构造和销毁方面)。我听说boost互斥不能静态初始化(很抱歉,我丢失了我读到它的链接),所以为了解决这个问题,我尝试了以下方法,如果threadsafety for construction and Destroyment是: static T& getInstance() { #ifndef STATIC_VARIABLES_ARE_THREADSAFE
static T& getInstance()
{
#ifndef STATIC_VARIABLES_ARE_THREADSAFE
boost::mutex mutex;
boost::lock_guard lock(mutex);
#endif
static T instance;
return instance;
}
这是线程安全的,还是应该使用boost::call_一次?boost once是否比这种方法有任何性能优势
编辑:
好吧,我的第一个想法显然不正确。澄清问题。boost::mutex可以安全地静态初始化吗?像这样:
class Singleton
{
private:
static boost::mutex m_mutex;
public:
static Singleton & getInstance()
{
boost::lock_guard lock(m_mutex);
static T instance;
return instance;
}
};
这是一种有效的方法,还是静态初始化boost::mutex实际上不安全(我就是这么读的)
EDIT2:
啊,顺便说一句,那是链接因为函数的每个条目都会创建自己的锁,锁将完全无用;任何数量的线程都可以进入函数,锁定不同的锁,同时开始处理静态数据 您可以在文件(或类静态)范围内创建锁;这将确保及时创建它,前提是您不在
main()
之前启动线程。但是,即使在初始化静态数据之后,这也会序列化函数的条目
为什么不首先在文件(或类静态)范围内定义静态数据?您确实需要使用锁定。但是,您建议的
boost::mutex
方案被破坏了,因为您在堆栈上分配了互斥体,多个并发调用方将各自获得自己的互斥体。GCC提供了静态变量的线程安全初始化。
因此,如果您使用GCC,您不需要关心静态变量的正确初始化尝试使用Meyers单例实现
class MySingleton {
public:
static MySingleton& getInstance() {
static MySingleton instance;
return instance;
}
private:
MySingleton();
~MySingleton();
MySingleton(const MySingleton&)= delete;
MySingleton& operator=(const MySingleton&)= delete;
};
MySingleton::MySingleton()= default;
MySingleton::~MySingleton()= default;
// Usage
int main() {
MySingleton::getInstance();
}
既然你这么说了,那就很明显了,谢谢!我想我得走boost/std::call_once路线了。boost互斥体不能静态初始化是真的吗?那么,我可以安全地静态初始化boost互斥体吗?如前所述,我在某个地方读到,情况并非如此,因此我不确定这是否是一种有效的方法。见更新后的帖子!将其初始化为函数范围静态变量是不安全的;这是因为进入函数的两个线程可能同时尝试初始化互斥锁本身。作为类级静态,只要在静态初始化完成之前不访问它,它是安全的(这是任何静态非POD类型的问题-请参阅)@bdonlan:注意,尽管这对于C++03是正确的,在C++中,静态本地保证线程安全的运行时初始化。这是一个选项。你检查了这个问题:C++中的线程安全的单线程()是有效的,但是我的问题是如果可以将静态互斥体静态初始化,因为如果是这样的话,这个问题很容易解决。单身是邪恶的,除非你真的。。。真的必须:)