`
superisaac
  • 浏览: 62906 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

一个pthread thread local的包装模板类

阅读更多
pthread 库提供了pthread_key_create, pthread_getspecific, pthread_setspecific方法操作.
原理上提供了一个 <key, pthread_t> ==> T的字典

pthread_getspecific(key) 方法的作用是<key, pthread_self()>查询这个字典, 得到对应的T*, 不同的线程, pthread_self不同, 自然会得到不同的返回值; 同一个线程中如果key不同, 也会得到不同的返回值.
理解了原理, 操作自然简单.

使用C++模板包装一下
#include <pthread.h>

template <class T>
class tls_factory
{
 public:
  T * create() {
    return new T;
  }
  void destroy(T* t) {
    delete t;
  }
};

template <class T, class factory_cls=tls_factory<T> >
class ThreadLocal
{
 private:
  pthread_key_t key;
  static void clear_tls(void * t) {
    if(t) {
      factory_cls factory;
      factory.destroy((T*)t);
    }
  }
 public:
  ThreadLocal() {
    pthread_key_create(&key, clear_tls);
  }

  T* get() {
    void * data = pthread_getspecific(key);
    if(data != NULL) {
      return (T*)data;
    } else {
      factory_cls factory;
      T * newT = factory.create();
      pthread_setspecific(key, newT);
      return newT;
    }
  }
  void set(T * newV) {
     void * data = pthread_getspecific(key);
     if(data != NULL) {
         clear_tls(data);
     }
     pthread_setspecific(newV);
  }

  T* operator->() {
      return get();
  }

  T& operator*() {
      return *get();
  } 
};

此间有个factory对象, 用来创建和销毁对象, 也可以自定义tls_factory 类作为模板参数传入, 用来定义对象的生成和销毁.

基本测试用例如
typedef struct {
  int value;
} AA;
ThreadLocal<AA> locala;
ThreadLocal<AA> localb;
void * __thread_func(void * v) {
  locala->value = 700;
  localb->value = 800;
  cout << "TA " << locala->value << endl;
  cout << "TB " << localb.get()->value << endl;
}

void test_threadlocal()
{
  pthread_t handle;
  locala.get()->value = 100;
  localb.get()->value = 200;

  pthread_create(&handle, NULL, __thread_func, NULL);
  pthread_join(handle, NULL);

  cout << "A " << locala.get()->value << endl;
  cout << "B " << localb->value << endl;
}



输出
TA 700
TB 800
A 100
B 200

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics