我实施了迈耶的单身人士模式。我尝试在多线程环境中测试它。以下是我在C ++中实现该类的方法。
#include<thread>
#include<mutex>
class singleton {
public:
static singleton& instance() {
std::lock_guard<std::mutex> lck(mtx);
static singleton *my = new singleton;
return *my;
}
private:
static std::mutex mtx;
singleton() {}
~singleton() {}
singleton(const singleton &) {}
singleton& operator=(const singleton &) {}
};
但是当我用g++ -std=c++11 singleton.cpp -o singleton -lpthread
编译它时,它说
/tmp/ccfEBnmN.o: In function `singleton::instance()':
singleton.cpp(.text._ZN11singleton12instanceEv[_ZN11singelton12instanceEv]+0x10):
undefined reference to `singleton::mtx' collect2: error: ld returned 1 exit status
我理解这可能是设计中的一些问题,因为没有初始化第一个单例实例我们怎么能得到mtx。如果在这种情况下,我的问题是如何基于我的代码实现线程安全的单例类?我们如何在我的单例类中初始化mtx?
我知道有一种传统方法可以通过维护指向单例类的静态指针来创建单例模式。但事实上,这不是&#34;所以&#34;线程安全。甚至在instance()方法中应用双重检查机制。
答案 0 :(得分:3)
您已在mtx
中声明了singleton
,但未能定义singleton
,这必须在std::mutex singleton::mtx;
之外,如下所示:
static singleton &instance() {
static singleton my;
return my;
}
这应该在源文件中,而不是标题(否则,如果在多个源文件中包含标题,则会出现多个定义错误。)
第二点:你所展示的是而不是一个迈耶的单身人士模式。对于Meyer的单例,您可以在函数内定义单例的静态实例:
{{1}}
使用它,根本不清楚你真的需要一个互斥锁。
答案 1 :(得分:0)
您的静态数据成员mtx
需要定义。将其放在源文件中:
std::mutex singleton::mtx;
更准确地说,std::lock_guard<std::mutex> lck(mtx)
odr-uses mtx
因此需要其定义。当链接器无法解析引用时,会出现链接时错误。
另请注意,在C ++ 11中,具有静态存储持续时间的对象的初始化是线程安全的,您不需要互斥锁。