19muduo_base库源码分析(十)

1.ThreadLocalSigleton类图

19muduo_base库源码分析(十)_第1张图片

每一个线程都有一个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 
#include 
#include 

namespace muduo
{

template
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
__thread T* ThreadLocalSingleton::t_value_ = 0;

template
typename ThreadLocalSingleton::Deleter ThreadLocalSingleton::deleter_;

}
#endif

ThreadLocalSingleton_test.cc

#include 
#include 
#include 

#include 
#include 
#include 

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::instance(),
         muduo::ThreadLocalSingleton::instance().name().c_str());
  muduo::ThreadLocalSingleton::instance().setName(changeTo);
  printf("tid=%d, %p name=%s\n",
         muduo::CurrentThread::tid(),
         &muduo::ThreadLocalSingleton::instance(),
         muduo::ThreadLocalSingleton::instance().name().c_str());

  // no need to manually delete it
  // muduo::ThreadLocalSingleton::destroy();
}

int main()
{
  muduo::ThreadLocalSingleton::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::instance(),
         muduo::ThreadLocalSingleton::instance().name().c_str());
  t2.join();

  pthread_exit(0);
}

运行结果:

19muduo_base库源码分析(十)_第2张图片

你可能感兴趣的:(muduo大并发服务器)