ThreadLocal class UML
ThreadLocal 的源代码
// 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:
//构造函数,创建pkey
ThreadLocal()
{
/*
创建的键存放在pkey指定的内存单元,这个键可以被进程中的所有线程使用,但每个线程
把这个键与不同的线程 “私有数据地址” 进行关联。创建新键时,每个线程的数据地址设为NULL值。
ThreadLocal::destructor键的虚构函数
**/
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 和 私有数据进行关联
pthread_setspecific(pkey_, newObj);
perThreadValue = newObj;
}
return *perThreadValue;
}
private:
static void destructor(void *x)
{
T* obj = static_cast<T*>(x);
//判断是否为全类型,如果是则delete obj,
typedef char T_must_be_complete_type[sizeof(T) == 0 ? -1 : 1];
delete obj;
}
private:
pthread_key_t pkey_;
};
}
#endifThreadLocal 的测试程序
#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
{
private :
std::string name_;
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 ;}
};
muduo::ThreadLocal<Test> testObj1;
muduo::ThreadLocal<Test> testObj2;
void print(){
printf("tid =%d\tobj1 %p\tname=%s\n",muduo::CurrentThread::tid(),
&testObj1.value(),
testObj1.value().name().c_str());
printf("tid=%d\tobj2 %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 2");
print();
}
int main (void ){
testObj1.value().setName("main One");
print();
muduo::Thread t1 (threadFunc) ;
t1.start();
t1.join();
testObj2.value().setName("main two" ) ;
print();
pthread_exit(0);
return 0 ;
}程序输出:
[root@localhost bin]# ./threadlocal_test
tid=2915,constructing 0x9435028
tid =2915 obj1 0x9435028 name=main One
tid=2915,constructing 0x9435038
tid=2915 obj2 0x9435038 name=
tid=2916,constructing 0xb6c00468
tid =2916 obj1 0xb6c00468 name=
tid=2916,constructing 0xb6c00478
tid=2916 obj2 0xb6c00478 name=
tid =2916 obj1 0xb6c00468 name=changed 1
tid=2916 obj2 0xb6c00478 name=changed 2
tid= 2916,destructing 0xb6c00468 changed 1
tid= 2916,destructing 0xb6c00478 changed 2
tid =2915 obj1 0x9435028 name=main One
tid=2915 obj2 0x9435038 name=main two
tid= 2915,destructing 0x9435028 main One
tid= 2915,destructing 0x9435038 main two
[root@localhost bin]# ls
本文详细解析ThreadLocal类的实现机制,包括其内部构造、使用方法及线程安全特性。通过实例演示ThreadLocal如何在多线程环境下为每个线程提供独立的数据存储空间,避免了全局变量带来的问题。
1492

被折叠的 条评论
为什么被折叠?



