ThreadLocal<T> 封装
在单线程程序中,我们经常要用到"全局变量"以实现多个函数间共享数据。
在多线程环境下,由于数据空间是共享的,因此全局变量也为所有线程所共有。
但有时应用程序设计中有必要提供线程私有的全局变量,仅在某个线程中有效,但却可以跨多个函数访问。
POSIX线程库通过维护一定的数据结构来解决这个问题,这个些数据称为(Thread-specific Data,或 TSD)。
线程特定数据也称为线程本地存储TLS(Thread-local storage)
对于POD类型的线程本地存储,可以用__thread关键字。非POD用TSD解决。
POSIX线程库用四个函数解决线程特定数据
pthread_key_create 一旦一个线程创建了一个key ,那么所以线程都有这个key,比如线程0有这个key,那么线程n 也有这个key。我们可以为特定的线程指定特定的数据,pthread_setspecific 来指定,pthread_getspecific 来获取。
pthread_key_delete 是删除的key ,而不是线程特定数据,删除数据是pthread_key_create 创建的时候指定回调函数,由回调函数来销毁数据,这个线程特定数据是堆上数据。
ThreadLocal<T> 的封装
// 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_;
};
}
#endif