19muduo_base库源码分析(十)

来源:互联网 发布:云端收银软件 编辑:程序博客网 时间:2024/06/03 04:09

1.ThreadLocalSigleton<T>类图


每一个线程都有一个T类型的单例对象

线程特定数据:

(1)POD类型可以使用__thread

(2)非POD类型使用pthread_key_create

2.代码

ThreadLocalSingleton.h

// Use of this source code is governed by a BSD-style license// that can be found in the License file.//// Author: Shuo Chen (chenshuo at chenshuo dot com)#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()  {    if (!t_value_)    {      t_value_ = new T();      deleter_.set(t_value_);    }    return *t_value_;  }  static T* pointer()  {    return t_value_;  } private:  static void destructor(void* obj)  {    assert(obj == t_value_);    typedef char T_must_be_complete_type[sizeof(T) == 0 ? -1 : 1];    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_;  };  static __thread T* t_value_;  static Deleter deleter_;};template<typename T>__thread T* ThreadLocalSingleton<T>::t_value_ = 0;template<typename T>typename ThreadLocalSingleton<T>::Deleter ThreadLocalSingleton<T>::deleter_;}#endif

ThreadLocalSingleton_test.cc

#include <muduo/base/ThreadLocalSingleton.h>#include <muduo/base/CurrentThread.h>#include <muduo/base/Thread.h>#include <boost/bind.hpp>#include <boost/noncopyable.hpp>#include <stdio.h>class Test : boost::noncopyable{ public:  Test()  {    printf("tid=%d, constructing %p\n", muduo::CurrentThread::tid(), this);  }  ~Test()  {    printf("tid=%d, destructing %p %s\n", muduo::CurrentThread::tid(), this, name_.c_str());  }  const std::string& name() const { return name_; }  void setName(const std::string& n) { name_ = n; } private:  std::string name_;};void threadFunc(const char* changeTo){  printf("tid=%d, %p name=%s\n",         muduo::CurrentThread::tid(),         &muduo::ThreadLocalSingleton<Test>::instance(),         muduo::ThreadLocalSingleton<Test>::instance().name().c_str());  muduo::ThreadLocalSingleton<Test>::instance().setName(changeTo);  printf("tid=%d, %p name=%s\n",         muduo::CurrentThread::tid(),         &muduo::ThreadLocalSingleton<Test>::instance(),         muduo::ThreadLocalSingleton<Test>::instance().name().c_str());  // no need to manually delete it  // muduo::ThreadLocalSingleton<Test>::destroy();}int main(){  muduo::ThreadLocalSingleton<Test>::instance().setName("main one");  muduo::Thread t1(boost::bind(threadFunc, "thread1"));  muduo::Thread t2(boost::bind(threadFunc, "thread2"));  t1.start();  t2.start();  t1.join();  printf("tid=%d, %p name=%s\n",         muduo::CurrentThread::tid(),         &muduo::ThreadLocalSingleton<Test>::instance(),         muduo::ThreadLocalSingleton<Test>::instance().name().c_str());  t2.join();  pthread_exit(0);}

运行结果: