linux TLS 线程本地变量

最近在写底层hook的时候, 涉及到线程安全问题, 最开始我设计的时候使用的互斥量, 但是考虑到都是底层函数,加锁会导致性能问题, 一直在思考优化方案, 后来偶然想到,java里面有线程本地变量的API, 或许linux也有, 问过度娘后发现还真有对应的API, 而且c++11的标准库里面也有实现, 不过我这暂时用不了c++11了, 就考虑封装一个, 下面是我的封装后的代码:

  template <typename T>
class ThreadLocal { public : explicit ThreadLocal() { pthread_key_create(&key, destory<T>); } ~ThreadLocal() { pthread_key_delete(key); } void set(T* value) { if (value != NULL) { void * old = pthread_getspecific(key); if (old != NULL) { delete old; } pthread_setspecific(key, value); } } void remove() { void *old = pthread_getspecific(key); if (old != NULL) { delete old; } pthread_setspecific(key, NULL); } T* get() { void * value = pthread_getspecific(key); if (value == NULL) { value = init(); pthread_setspecific(key, value); } return (T *)value; }
     template<typename U> static
void destory(void * value) { if (value != NULL) { U * v = (U *)value; delete v; } } protected: T * init() { T *ret = new T (); return ret; } private: pthread_key_t key; }; }
  1. 首先pthread_key_create()方法会创建一个关联, 键值为key,  java里面线程中使用threadlocal作为key, 数据作为value,存放在ThreadLocalMap中, 嘛,这里就不介绍java的了。 主要是在进层空间的一个数组中添加记录。
  2. 然后pthread_key_delete()这个方法就是删除由create方法在进程空间的数组中的记录了,一般linux一个进程的key的数量是有限制的, 所以不用了就删除掉,如果线程本地变量比较多,可以考虑将这些封装到一个数据结构里,用一个key映射。
  3. pthread_getspecific()方法主要是获取当前线程与key关联的数据了, 这里也有可能返回的是NULL(可能是我们释放掉了,赋值为null了)
  4. pthread_setspecific()方法主要是设置key关联的数据了

      

具体的说明可以看这篇博客, 写的很不错 http://blog.csdn.net/cywosp/article/details/26469435

原文地址:https://www.cnblogs.com/zhangyan-2015/p/5967334.html