18muduo_base库源码分析(九)
来源:互联网 发布:linux mint中文输入法 编辑:程序博客网 时间:2024/06/11 03:51
1.线程特定数据
(1)在单线程程序中,我们经常要用到"全局变量"以实现多个函数间共享数据。
(2)在多线程环境下,由于数据空间是共享的,因此全局变量也为所有线程所共有。
(3)但有时应用程序设计中有必要提供线程私有的全局变量,仅在某个线程中有效,但却可以跨多个函数访问。
(4)POSIX线程库通过维护一定的数据结构来解决这个问题,这个些数据称为(Thread-specific Data,或 TSD)。
(5)线程特定数据也称为线程本地存储TLS(Thread-local storage)
(6)对于POD类型的线程本地存储,可以用__thread关键字
2.ThreadLocal<T>类图
3.代码
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() { pthread_key_create(&pkey_, &ThreadLocal::destructor); } ~ThreadLocal() { 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; } private: pthread_key_t pkey_;};}#endifThreadLocal_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().setName("changed 1"); testObj2.value().setName("changed 42"); print();}int main(){ testObj1.value().setName("main one"); print(); muduo::Thread t1(threadFunc); t1.start(); t1.join(); testObj2.value().setName("main two"); print(); pthread_exit(0);
运行结果
#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_;};#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"); 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);}运行结果:Threadlocal<Test>类型是单例,muduo::Singletion<muduo::Threadlocal<Test>>::instance,每一个线程中只会有一个Test类的对象(因为是单例,不像第一个例子一个线程中会存在两个Test类对象,不是每个线程只能有一个特定属性Threadlocal),但是每一个线程都会有Test类对象
阅读全文
1 0
- 18muduo_base库源码分析(九)
- 11muduo_base库源码分析(二)
- 12muduo_base库源码分析(三)
- 13muduo_base库源码分析(四)
- 15muduo_base库源码分析(六)
- 16muduo_base库源码分析(七)
- 17muduo_base库源码分析(八)
- 19muduo_base库源码分析(十)
- 20muduo_base库源码分析(十一)
- muduo_base 源码分析:Timestamp
- muduo_base 源码分析:AtomicIntegerT
- 高并发服务器架构笔记(3)——muduo_base 源码分析
- 高并发服务器架构笔记(3)——muduo_base 源码分析
- 33muduo_net库源码分析(九)
- Caffe 源码(九):euclidean_loss_layer 分析
- appium源码分析(九)-getText,setText
- scrapy源码分析(九)-----------Scheduler
- springMVC源码分析--ControllerClassNameHandlerMapping(九)
- 2.0-Spark完全分布式集群安装
- 搭建WordPress
- 备份map类型
- 数据结构 斐波那契查找
- R语言svm支持向量机分类与参数优化
- 18muduo_base库源码分析(九)
- 微信小程序开发(三)--交互反馈
- Android 在机顶盒开发过程当中如何禁止listview的item项获得焦点,而让item的子控件获得焦点
- c语言柔性数组实现并用其求Fibonacci数列前n项,不足之处请见谅并回复评价
- C++对缓冲区的理解
- Linux系统的firewalld服务
- [NOIP模拟赛]TPS
- POJ-2406 Power Strings(KMP求重复子串出现的最大次数)
- 【单片机笔记】51内核软件延时和串口的巧妙使用方法