您的位置:首页 > 运维架构 > Linux

C++ linux线程安全单例Singleton

2016-07-03 16:15 615 查看
DCL(double checked locking)

//class singleton
//:s1-
singleton* get_instance(void)
{
lock();
if( instance == 0) {
instance = new singleton;
}
unlock();
return instance;
}

**存在的问题是:无论是否已经初始化都要加锁,增加了负荷,已经没有所谓的并发性能了。
//:s-2
singleton* get_instance(void)
{
if( instance == 0){
lock();
instance = new singleton;
unlock();
}
return instance;
}


**存在的问题是:不能保证临界区只初始化一次,没能实现singleton的基本功能;
//:s-3
singleton* get_instance(void)
{
if( instance == 0){
lock();
if( instance == 0 )
instance = new singleton;
unlock();
}
return instance;
}


**解决路上述问题——双检锁模式,兼顾了效率和正确性。还来有人指出由于乱序执行的影响,DCL是靠不住的。

可以借助其他语言的一些机制,如eager initialization,memory barrier。

不过,如果支持pthread的话,可以站在巨人的肩膀,pthread_once

int pthread_once(pthread_once_t *once_control, void (*init_routine) (void));

功能:本函数使用初值为PTHREAD_ONCE_INIT的once_control变量保证init_routine()函数在本进程执行序列中仅执行一次。
在多线程编程环境下,尽管pthread_once()调用会出现在多个线程中,init_routine()函数仅执行一次,究竟在哪个线程中执行是不定的,是由内核调度来决定。

线程安全性由Pthreads库保证。

template<typename T>
class Singleton:boost::noncopyable
{
public:
static T& instance()
{
pthread_once(&ponce_, &Singleton::init);
return *value_;
}

private:
Singleton();
~Singleton();

static void init()
{
value_ = new T();
}

private:
static pthread_once_t ponce_;
static T* value_;
}

//必须在头文件中定义static 变量
template<typename T>
pthread_once_t Singleton<T>::ponce_ = PTHREAD_ONCE_INIT;

template<typename T>
T* Singleton<T>::value_ = NULL;


注意这里没有考虑对象销毁
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: