muduo库的ThreadLocalSingleton类剖析


本文剖析muduo库的ThreadLocalSingleton类,即线程本地单例类。


先来看下它的类图,它的内部嵌套的一个deleter类。




分析如下:

#ifndef MUDUO_BASE_THREADLOCALSINGLETON_H
#define MUDUO_BASE_THREADLOCALSINGLETON_H

#include <boost/noncopyable.hpp>
#include <assert.h>
#include <pthread.h>

namespace muduo
{

template<typename T>
class ThreadLocalSingleton : boost::noncopyable
{
 public:

  static T& instance() //返回单例对象,不需要按照线程安全方式实现,因为本身就是__thread类型
  {
    if (!t_value_)   //如果指针为空创建
    {
      t_value_ = new T();
      deleter_.set(t_value_);    //把t_value_指针暴露给deleter,为了垃圾回收
    }
    return *t_value_;
  }

  static T* pointer()
  {
    return t_value_;
  }

 private:
  ThreadLocalSingleton();
  ~ThreadLocalSingleton();

  static void destructor(void* obj)   //内层类中线程结束时,会调用此函数取清理key指向的数据
  {
    assert(obj == t_value_);
    typedef char T_must_be_complete_type[sizeof(T) == 0 ? -1 : 1];
    T_must_be_complete_type dummy; (void) dummy;
    delete t_value_;
    t_value_ = 0;
  }

  class Deleter
  {
   public:
    Deleter()
    {
      pthread_key_create(&pkey_, &ThreadLocalSingleton::destructor);  //设置外面类的destructor方法,
    }

    ~Deleter()
    {
      pthread_key_delete(pkey_);
    }

    void set(T* newObj)
    {
      assert(pthread_getspecific(pkey_) == NULL);   //保证之前key没有指向数据
      pthread_setspecific(pkey_, newObj);   //现在设置key指向newobj指针,在ThreadLocalSingleton中会传入t_value_指针,
     	//实际上是为了实现垃圾回收,线程结束时,deleter调用destroy,释放key指向的数据,而这个数据正好就是外部类的成员t_value_指针					    
    }

    pthread_key_t pkey_;
  };

  static __thread T* t_value_;   //__thread关键字保证线程局部属性,只能修饰POD类型
  static Deleter deleter_;   //用来销毁T*指针所指对象
};

template<typename T>
__thread T* ThreadLocalSingleton<T>::t_value_ = 0;

template<typename T>
typename ThreadLocalSingleton<T>::Deleter ThreadLocalSingleton<T>::deleter_;

}

ThreadLocalSingleton和Singleton<ThreadLocal<test>>

(ThreadLocal是上篇博客说过的,线程局部类)

实际上都是一样的,前者是直接集成化单例和线程局部,后者是产生一个单例的模板,然后把线程局部对象以模板参数形式传入,也变成了单例对象。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值