17muduo_base库源码分析(八)

来源:互联网 发布:软件维护工程师 编辑:程序博客网 时间:2024/06/05 10:23

1.Singleton类图


线程安全Singleton类实现
(1)pthread_once
(2)atexit
(3)typedef char T_must_be_complete_type[sizeof(T) == 0 ? -1 : 1];

2.代码

Singleton.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_SINGLETON_H#define MUDUO_BASE_SINGLETON_H#include <boost/noncopyable.hpp>#include <pthread.h>#include <stdlib.h> // atexitnamespace muduo{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();    ::atexit(destroy);  }  static void destroy()  {    typedef char T_must_be_complete_type[sizeof(T) == 0 ? -1 : 1];    delete value_;  } private:  static pthread_once_t ponce_;  static T*             value_;};template<typename T>pthread_once_t Singleton<T>::ponce_ = PTHREAD_ONCE_INIT;template<typename T>T* Singleton<T>::value_ = NULL;}#endif
Singleton_test.cc
#include <muduo/base/Singleton.h>#include <muduo/base/CurrentThread.h>#include <muduo/base/Thread.h>#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 muduo::string& name() const { return name_; }  void setName(const muduo::string& n) { name_ = n; } private:  muduo::string name_;};void threadFunc(){  printf("tid=%d, %p name=%s\n",         muduo::CurrentThread::tid(),         &muduo::Singleton<Test>::instance(),         muduo::Singleton<Test>::instance().name().c_str());  muduo::Singleton<Test>::instance().setName("only one, changed");}int main(){  muduo::Singleton<Test>::instance().setName("only one");  muduo::Thread t1(threadFunc);  t1.start();  t1.join();  printf("tid=%d, %p name=%s\n",         muduo::CurrentThread::tid(),         &muduo::Singleton<Test>::instance(),         muduo::Singleton<Test>::instance().name().c_str());}

运行结果