我目前正在尝试使用boost :: mutex编写线程安全单例(至少在构造和破坏方面)。我读到boost mutex无法静态初始化(我丢失了我读到它的链接,抱歉)所以要解决这个问题,我试过这个,如果构造和破坏的线程安全:
static T& getInstance()
{
#ifndef STATIC_VARIABLES_ARE_THREADSAFE
boost::mutex mutex;
boost::lock_guard lock(mutex);
#endif
static T instance;
return instance;
}
是线程安全的,还是应该使用boost :: call_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 : 啊,那就是http://uint32t.blogspot.com/2007/12/you-lazy-bastard-part-1.html
的方式答案 0 :(得分:3)
由于函数的每个条目都会创建自己的锁,因此锁将完全无用;任意数量的线程都可以进入该函数,锁定不同的锁,同时开始搞乱静态数据。
您可以在文件(或类静态)范围内创建锁;如果您不在main()
之前启动线程,这将确保及时创建它。但是,即使在初始化静态数据之后,这也会序列化函数的输入。
为什么不首先在文件(或类静态)范围内定义静态数据?
答案 1 :(得分:1)
GCC提供静态变量的线程安全初始化。 因此,如果您使用GCC,则无需关心静态变量的正确初始化
答案 2 :(得分:0)
您确实需要使用锁定。但是,您建议的boost::mutex
方案已被破坏,因为您在堆栈上分配互斥锁,并且多个并发调用方将各自获得自己的互斥锁。
答案 3 :(得分:0)