zoukankan      html  css  js  c++  java
  • muduo网络库源码学习————线程特定数据

    muduo库线程特定数据源码文件为ThreadLocal.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_THREADLOCAL_H
    #define MUDUO_BASE_THREADLOCAL_H
    
    #include <boost/noncopyable.hpp>
    #include <pthread.h>
    
    namespace muduo
    {
    
    template<typename T>
    class ThreadLocal : boost::noncopyable//不可拷贝
    {
     public:
      ThreadLocal()
      {//构造函数创建key,ThreadLocal::destructor为销毁的回调函数
        pthread_key_create(&pkey_, &ThreadLocal::destructor);
      }
    
      ~ThreadLocal()
      {//析构函数销毁key,但并不是销毁实际的数据
        pthread_key_delete(pkey_);
      }
    
      T& value()
      {//获取线程特定数据
        T* perThreadValue = static_cast<T*>(pthread_getspecific(pkey_));
        if (!perThreadValue) //返回指针如果是空,说明特定数据还没有创建
        {
          T* newObj = new T();//创建数据
          pthread_setspecific(pkey_, newObj);//设定特定数据
          perThreadValue = newObj;
        }
        return *perThreadValue;//返回特定数据
      }
    
     private:
      //作为回调函数销毁实际的数据
      static void destructor(void *x)
      {
        T* obj = static_cast<T*>(x);
        typedef char T_must_be_complete_type[sizeof(T) == 0 ? -1 : 1];//完全类型
        delete obj;//调用delete销毁数据
      }
    
     private:
      pthread_key_t pkey_;
    };
    
    }
    #endif
    

    有两个测试程序
    ThreadLocal_test.cc

    //线程本地存储测试程序
    #include <muduo/base/ThreadLocal.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
    ", muduo::CurrentThread::tid(), this);
      }
    
      ~Test()
      {
        printf("tid=%d, destructing %p %s
    ", 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_;
    };
    //定义两个线程特定数据对象,每个线程都有这样的对象
    muduo::ThreadLocal<Test> testObj1;
    muduo::ThreadLocal<Test> testObj2;
    
    void print()//打印函数
    {
      printf("tid=%d, obj1 %p name=%s
    ",muduo::CurrentThread::tid(),&testObj1.value(),testObj1.value().name().c_str());
      printf("tid=%d, obj2 %p name=%s
    ",muduo::CurrentThread::tid(),&testObj2.value(),testObj2.value().name().c_str());
    }
    
    void threadFunc()
    {
      print();
      //testObj1.value()返回的是Test类型的引用
      testObj1.value().setName("changed 1");
      testObj2.value().setName("changed 42");
      print();
    }
    
    int main()
    {
      testObj1.value().setName("main one");
      print();
      //创建线程,每个线程都有自己的testObj1,testObj2
      muduo::Thread t1(threadFunc);
      t1.start();//启动线程
      t1.join();
      testObj2.value().setName("main two");
      print();
    
      pthread_exit(0);//退出主线程
    }
    

    执行结果如下:
    这里写图片描述

    SingletonThreadLocal_test.cc

    #include <muduo/base/Singleton.h>
    #include <muduo/base/CurrentThread.h>
    #include <muduo/base/ThreadLocal.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
    ", muduo::CurrentThread::tid(), this);
      }
    
      ~Test()
      {
        printf("tid=%d, destructing %p %s
    ", 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_;
    };
    //单例对象:muduo::Singleton<muduo::ThreadLocal<Test> >::instance(),value是线程特定数据,每个线程都有的
    #define STL muduo::Singleton<muduo::ThreadLocal<Test> >::instance().value()
    
    void print()
    {//打印函数
      printf("tid=%d, %p name=%s
    ",muduo::CurrentThread::tid(),&STL,STL.name().c_str());
    }
    
    void threadFunc(const char* changeTo)
    {
      print();
      STL.setName(changeTo);//设置线程特定数据的名称
      sleep(1);//睡眠
      print();
    }
    
    int main()
    {
      STL.setName("main one");//设置线程特定数据的名称
      //创建两个线程,threadFunc带参数
      muduo::Thread t1(boost::bind(threadFunc, "thread1"));
      muduo::Thread t2(boost::bind(threadFunc, "thread2"));
      //启动两个线程
      t1.start();
      t2.start();
      t1.join();
      print();
      t2.join();
      pthread_exit(0);
    }
    

    执行结果如下:
    这里写图片描述

  • 相关阅读:
    Hello World
    函数
    js基础
    html
    npm
    数据库
    前端了解的简要php
    模块
    scrapy爬虫
    php升级代码检查
  • 原文地址:https://www.cnblogs.com/sigma0-/p/12630480.html
Copyright © 2011-2022 走看看