C++ 中的线程安全单例实现
Posted
技术标签:
【中文标题】C++ 中的线程安全单例实现【英文标题】:Thread safe singleton implementation in C++ 【发布时间】:2009-06-27 12:02:16 【问题描述】:以下是众所周知的 C++ 中单例模式的实现。 但是,我不完全确定它是否是线程安全的。 根据之前在此处提出的类似问题的答案,它似乎是线程安全的。 是这样吗?
//Curiously Recurring Template Pattern
//Separates a class from its Singleton-ness (almost).
#include <iostream>
using namespace std;
template<class T> class Singleton
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
protected:
Singleton()
virtual ~Singleton()
public:
static T& instance()
static T theInstance;
return theInstance;
;
// A sample class to be made into a Singleton
class MyClass : public Singleton<MyClass>
int x;
protected:
friend class Singleton<MyClass>;
MyClass() x = 0;
public:
void setValue(int n) x = n;
int getValue() const return x;
;
【问题讨论】:
你为什么要把它做成一个 WIKI?这是一个完全有效的问题。 你没有给出任何理由说明你认为模式实现不是线程安全的。请做。 这里的朋友班的目的是什么?有人可以回答吗? 哦,拍!应该检查常见问题以了解它的含义,而不是假设它是什么。 @Ahmed。它用于编译语句“static T theInstance”。如您所见,MyClass 具有受保护的构造函数,因此我们需要朋友说明符,以便 Singleton 类(准确地说是 Singleton不,这不是线程安全的,因为静态本地没有以任何方式受到保护。默认情况下,静态本地不是线程安全的。这意味着您可能会遇到以下问题
单例的构造函数多次运行 不能保证对静态的分配是原子的,因此您可以在多线程场景中看到部分分配 我可能还缺少一些。这是 Raymond Chen 的详细博客文章,介绍了为什么 C++ 静态在默认情况下不是线程安全的。
http://blogs.msdn.com/oldnewthing/archive/2004/03/08/85901.aspx【讨论】:
所以基本上这意味着不可能使用 C++ 做一个与操作系统无关的单例?也就是说,你总是需要一些关键部分或类似的部分来做一个?【参考方案2】:它不是线程安全的。 为了变得线程安全,您应该在锁之前添加一个检查(信号量锁)并在锁之后添加另一个检查。然后您可以确定,即使在来自不同线程的同时调用中,您也可以提供一个实例。
【讨论】:
【参考方案3】:它不是线程安全的,除非您将编译器配置为为静态访问生成线程安全代码。
不过,代码最好是独立的,所以我会在这里和那里添加一个互斥锁。
【讨论】:
【参考方案4】:如果您仍然对此主题感兴趣并且正在使用 C++ 11 标准编译器,您可以找到 here 一个关于多线程环境中单例模式的提议。
【讨论】:
以上是关于C++ 中的线程安全单例实现的主要内容,如果未能解决你的问题,请参考以下文章