单例+特定数据
// Singleton 所管理的对象是 ThreadLocal<Test> ,
ThreadLocal<Test> 在进程内是单例,
所有线程共一个ThreadLocal<Test> 实例
Singleton调用instance方法获取
ThreadLocal<Test>
实例,
ThreadLocal<Test>实例
调用
ThreadLocal<Test>::
value方法获取Test类型线程特定数据的引用,value返回的是各自线程特定数据引用。
Singleton确保进程范围内单例,ThreadLocal<Test>实例只有一个,所有线程共这一个ThreadLocal<Test>实例
(所以
Singleton内部要加锁初始化实例,或者用pthread_once初始化实例
)
;ThreadLocal确保Test有多个,即在每个线程都有自己特定的
(由于
ThreadLocal<Test>已经是单例了,定了不会有新的出现了 pthread_key_t key_一直是那一个,所以其实Test在每个线程也是只有一个,也是线程中的单例了
)
#define STL muduo::Singleton<muduo::ThreadLocal<Test> >::instance().value()
多个线程的instance( ) 返回同一个进程范围内单例实例,value( )返回本线程特定数据实例Test的引用
线程特定+单例:ThreadLocalSigleton
所有线程都有自己的一份,且都只有一个,即在线程范围内它是单例,一直存在的,静态的,
ThreadLocalSigleton<Test> ::instance( ): 返回本线程Test单例实例的引用,线程内单例.每次都是这一个static __pthreadT*
ThreadLocal<Test> t:每调用默认构造函数(没有括号,参数),每次都会new 一个Test 实例 t 给本线程
muduo::Singleton<muduo::ThreadLocal<Test> >::instance().value() 与 ThreadLocalSigleton<Test> ::instance( )
两者其实都是在线程中实现了单例,效果一样
#ifndef MUDUO_BASE_THREADLOCALSIGLETON_H
#define MUDUO_BASE_THREADLOCALSIGLETON_H
#include <boost/noncopyable.hpp>
#include <assert.h>
#include <pthread.h>
namespace muduo
{
template<typename T>
class ThreadLocalSingleton : boost::noncopyable
{
public:
//注意是静态,获取同一个实例-单例,t_value_ 是__thread 修饰的,线程私有,所以不要加锁
static T& instance()
{
if(t_value_ == NULL)
{
t_value_ = new T();
deleter_.set(t_value_);//注册删除释放,t_value_指针在pthread_key_t中也存了一份,用于删除释放内存
}
return *t_value_;
}
static T* pointer()
{
return t_value_;
}
private:
//ThreadLocalSingleton只提供了静态方法instance(),获取单例用的是静态方法,没有实例化对象,所以就没有析构,就不要在析构函数中释放T*;即使用成员非静态instance(先实例化ThreadLocalSingleton),如果析构函数中释放了T*,那下次获取的时候会是重新new的,那就不是单例了
static void destructor(void* obj)
{
assert(obj == t_value_);//
typedef char T_must_be_complete_type[sizeof(T) == 0 ? -1 : 1];
T_must_be_complete_type tt;(void) tt;
delete t_value_;
t_value_ = 0;
}
class Deleter
{
public:
Deleter()
{
pthread_key_create(&pkey_, &ThreadLocalSingleton::destructor);
}
~Deleter()
{
pthread_key_delete(pkey_);
}
void set(T* newObj)
{
assert(pthread_getspecific(pkey_) == NULL);
pthread_setspecific(pkey_, newObj);
}
pthread_key_t pkey_;
};
private:
static __thread T* t_value_;//单例,线程生命周期内都只有一个T*,所以要静态
static Deleter deleter_;//整个进程只需要一个pthread_key_t key(一级索引),所以静态,某个线程退出就析构某个线程特定数据T* 调用ThreadLocalSingleton::destructor,TSD不是要等进程退出了析构deleter时才一次性全部析构线程特定数据,析构deleter时调用pthread_key_delete(key_)只是删除key。
};
template<typename T>
__thread T* ThreadLocalSingleton<T>::t_value_=NULL;
template<typename T>
typename ThreadLocalSingleton<T>::Deleter ThreadLocalSingleton<T>::deleter_;//默认构造函数初始化成员变量ThreadLocalSingleton::deleter_; typename 修饰 ThreadLocalSingleton<T>::Deleter表明 Deleter 是模板中的类型
}
#endif
参考:c++教程网