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

 

 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

 

相关文章:

  • 2021-11-25
  • 2022-12-23
  • 2021-11-17
  • 2021-07-04
  • 2021-09-09
  • 2021-06-10
  • 2022-12-23
猜你喜欢
  • 2021-05-26
  • 2022-02-12
  • 2021-04-16
  • 2021-11-23
  • 2021-12-01
  • 2021-09-02
相关资源
相似解决方案