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\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_;
};
//定义两个线程特定数据对象,每个线程都有这样的对象
muduo::ThreadLocal<Test> testObj1;
muduo::ThreadLocal<Test> testObj2; void print()//打印函数
{
printf("tid=%d, obj1 %p name=%s\n",muduo::CurrentThread::tid(),&testObj1.value(),testObj1.value().name().c_str());
printf("tid=%d, obj2 %p name=%s\n",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\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_;
};
//单例对象:muduo::Singleton<muduo::ThreadLocal<Test> >::instance(),value是线程特定数据,每个线程都有的
#define STL muduo::Singleton<muduo::ThreadLocal<Test> >::instance().value() void print()
{//打印函数
printf("tid=%d, %p name=%s\n",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);
}

执行结果如下:

muduo网络库源码学习————线程特定数据的更多相关文章

  1. muduo网络库源码学习————线程本地单例类封装

    muduo库中线程本地单例类封装代码是ThreadLocalSingleton.h 如下所示: //线程本地单例类封装 // Use of this source code is governed b ...

  2. muduo网络库源码学习————线程池实现

    muduo库里面的线程池是固定线程池,即创建的线程池里面的线程个数是一定的,不是动态的.线程池里面一般要包含线程队列还有任务队列,外部程序将任务存放到线程池的任务队列中,线程池中的线程队列执行任务,也 ...

  3. muduo网络库源码学习————线程类

    muduo库里面的线程类是使用基于对象的编程思想,源码目录为muduo/base,如下所示: 线程类头文件: // Use of this source code is governed by a B ...

  4. muduo网络库源码学习————线程安全

    线程安全使用单例模式,保证了每次只创建单个对象,代码如下: Singleton.h // Use of this source code is governed by a BSD-style lice ...

  5. muduo网络库源码学习————Timestamp.cc

    今天开始学习陈硕先生的muduo网络库,moduo网络库得到很多好评,陈硕先生自己也说核心代码不超过5000行,所以我觉得有必要拿过来好好学习下,学习的时候在源码上面添加一些自己的注释,方便日后理解, ...

  6. muduo网络库源码学习————互斥锁

    muduo源码的互斥锁源码位于muduo/base,Mutex.h,进行了两个类的封装,在实际的使用中更常使用MutexLockGuard类,因为该类可以在析构函数中自动解锁,避免了某些情况忘记解锁. ...

  7. muduo网络库源码学习————日志滚动

    muduo库里面的实现日志滚动有两种条件,一种是日志文件大小达到预设值,另一种是时间到达超过当天.滚动日志类的文件是LogFile.cc ,LogFile.h 代码如下: LogFile.cc #in ...

  8. muduo网络库源码学习————日志类封装

    muduo库里面的日志使方法如下 这里定义了一个宏 #define LOG_INFO if (muduo::Logger::logLevel() <= muduo::Logger::INFO) ...

  9. muduo网络库源码学习————无界队列和有界队列

    muduo库里实现了两个队列模板类:无界队列为BlockingQueue.h,有界队列为BoundedBlockingQueue.h,两个测试程序实现了生产者和消费者模型.(这里以无界队列为例,有界队 ...

随机推荐

  1. Python常见数据结构-Dictionary字典

    字典基本特点 字典的每个键值 key=>value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {} 中. 键是唯一的,如果重复最后的一个键值对会替换前面的,值不需 ...

  2. String 对象-->substring() 方法

    1.定义和用法 substring() 方法用于提取两个指定下标之间的字符. substring() 方法返回的子串包括 开始 处的字符,但不包括 结束 处的字符 语法: string.substri ...

  3. Idea离线安装plugins插件 如Lombok

    由于公司不允许使用外网,之前用的idea 15 安装了一次.但是idea15的提示不够友好,今天升级idea2017.3.2,同样又需要安装,那就写个教程吧. 网上其他的安装教程不通用,也是针对不同i ...

  4. Java接口和抽象类有什么区别,哪些时候用接口,哪些时候用抽象类?

    Java接口和抽象类有什么区别,哪些时候用接口,哪些时候用抽象类? 2013-01-05 17:16:09|  分类: JAVA |  标签:java  |举报|字号 订阅     下面比较一下两者的 ...

  5. CNVD

    漏洞编号 漏洞名称 漏洞积分 奖励时间 CNVD-2020-15798 中国平乐县委员会组织部网站管理系统登录存在弱口令漏洞 1.0 2020-03-09 09:58:46.0 CNVD-2020-1 ...

  6. 【Java】封装、继承、多态

    封装 在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部分包装.隐藏起来的方法. 封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代 ...

  7. HashMap主要方法源码分析(JDK1.8)

    本篇从HashMap的put.get.remove方法入手,分析源码流程 (不涉及红黑树的具体算法) jkd1.8中HashMap的结构为数组.链表.红黑树的形式     (未转化红黑树时)   (转 ...

  8. L13过拟合欠拟合及其解决方案

    过拟合.欠拟合及其解决方案 过拟合.欠拟合的概念 权重衰减 丢弃法 模型选择.过拟合和欠拟合 训练误差和泛化误差 在解释上述现象之前,我们需要区分训练误差(training error)和泛化误差(g ...

  9. Mysql大厂高频面试题

    前言 前几天有读者找到我,说想要一套全面的Mysql面试题,今天陈某特地为她写了一篇. 文章的目录如下: Mysql面试题 什么是SQL? 结构化查询语言(Structured Query Langu ...

  10. F - Distinct Numbers

    链接:https://atcoder.jp/contests/abc143/tasks/abc143_f 题解:开两个数组,其中一个arr用来保存每个元素出现的次数,同时再开一个数组crr用来保存出现 ...