C++线程局部存储(TLS)
来源:互联网 发布:macbook下软件好下吗 编辑:程序博客网 时间:2024/06/09 19:38
基本类型(如(unsigned) int,long, char,指针,c类型的结构体等 )可以采用用 __thread修饰符来定义线程局部变量.
示例如下:
__thread int i;extern __thread struct state s;static __thread char *p;
像 string 等类是不能直接用 __thread 修符的,只能用其指针类型的.即:
1
__thread std::string * p_thread_name;
使用 __thread修饰符来定义一些类的线程局部变量,往往容易造成内存泄漏.
网上实现的Tls类,可以方便用户使用!
头文件:
//Tls.h#ifndef __SAP_UTIL_TLS_H_#define __SAP_UTIL_TLS_H_#include <pthread.h> class Tls{public: static int pthread_atexit_add(void *arg, void (*free_fn)(void *) ); static int pthread_atexit_remove(void *arg, void (*free_fn)(void*) );protected: static void pthread_atexit_done(void *arg); static void pthread_atexit_init(void);protected: static pthread_key_t _pthread_atexit_key; static pthread_once_t _pthread_atexit_control_once;}; #endif实现文件:
// Tls.cpp#include <sys/syscall.h>#include <list>#include "Tls.h" using namespace std; #define gettid() syscall(__NR_gettid)#define TLS_OUT_OF_INDEXES 0xffffffff typedef struct pthread_atexit{ void (*free_fn)(void *); void *arg;}pthread_atexit_t; typedef std::list<pthread_atexit_t *> TlsList; pthread_key_t Tls::_pthread_atexit_key = TLS_OUT_OF_INDEXES;pthread_once_t Tls::_pthread_atexit_control_once = PTHREAD_ONCE_INIT; void Tls::pthread_atexit_done(void *arg){ TlsList *id_list = (TlsList*) arg; pthread_atexit_t *id_ptr=NULL; printf("invoke Tls::pthread_atexit_done(): tid=%ld\n",gettid()); for(TlsList::iterator iter=id_list->begin(); iter !=id_list->end(); ++iter) { id_ptr = *iter; if (id_ptr == NULL) continue; if (id_ptr->free_fn) id_ptr->free_fn(id_ptr->arg); delete id_ptr; } delete id_list;} void Tls::pthread_atexit_init(void){ pthread_key_create(&_pthread_atexit_key, pthread_atexit_done);} int Tls::pthread_atexit_add(void *arg, void (*free_fn)(void *)){ const char *myname = "pthread_atexit_add"; pthread_atexit_t *id; TlsList *id_list; if (arg == NULL) { return 0; } pthread_once(&_pthread_atexit_control_once, pthread_atexit_init); if (_pthread_atexit_key == (pthread_key_t) TLS_OUT_OF_INDEXES) { printf("%s(%d): _pthread_atexit_key(%d) invalid\n", myname, __LINE__, _pthread_atexit_key); return (-1); } id = new pthread_atexit_t; if (id == NULL) { printf("%s(%d): new pthread_atexit_t error\n", myname, __LINE__); return -1; } id->free_fn = free_fn; id->arg = arg; id_list = (TlsList*) pthread_getspecific(_pthread_atexit_key); if (id_list == NULL) { id_list = new TlsList(); if (pthread_setspecific(_pthread_atexit_key, id_list) != 0) { printf("%s(%d): pthread_setspecific error, key(%d)\n", myname, __LINE__, _pthread_atexit_key); return -1; } } id_list->push_back(id); return 0;} int Tls::pthread_atexit_remove(void *arg, void (*free_fn)(void*)){ const char *myname = "pthread_atexit_remove"; TlsList *id_list; if (arg == NULL) { return (-1); } if (_pthread_atexit_key == (pthread_key_t) TLS_OUT_OF_INDEXES) { printf("%s(%d): _pthread_atexit_key(%d) invalid\n",myname, __LINE__, _pthread_atexit_key); return (-1); } id_list = (TlsList*) pthread_getspecific(_pthread_atexit_key); if (id_list == NULL) { printf("%s(%d): _pthread_atexit_key(%d) no exist in tid(%lu)\n", myname, __LINE__, _pthread_atexit_key,(unsigned long) pthread_self()); return (-1); } pthread_atexit_t *id_ptr =NULL; TlsList::iterator iter=id_list->begin(); for(; iter !=id_list->end(); ++iter) { id_ptr = *iter; if (id_ptr == NULL) continue; if (id_ptr->free_fn == free_fn && id_ptr->arg == arg) { break; } } if(id_ptr != NULL) { id_list->erase(iter); delete id_ptr; } return (0);}
使用方法:
1) #include “Tls.h”
2) 用 __thread 声明某类型的线程局部变量指针
3) 定义该线程局部变量的内存释放函数
4) 第一次使用该线程局部变量时,分配内存并调用pthread_atexit_add注册内存释放函数
更多参考:点击打开链接
0 0
- 线程局部存储TLS
- 线程局部存储TLS
- TLS--线程局部存储
- 线程局部存储(TLS)
- 线程局部存储(TLS)
- TLS--线程局部存储
- 线程局部存储TLS
- TLS--线程局部存储
- TLS--线程局部存储
- TLS--线程局部存储
- TLS--线程局部存储
- TLS---线程局部存储
- 线程局部存储TLS
- TLS线程局部存储
- 线程局部存储TLS
- TLS--线程局部存储
- TLS--线程局部存储
- TLS线程局部存储
- [Leetcode] Unique Binary Search Trees II
- QT5入门之14 - QString
- IE不支持getElementsByClassName最终完美解决方案
- 补码的理解
- MJRefresh使用方法
- C++线程局部存储(TLS)
- 详解Qt样式/颜色机制:调色板(QPalette)与样式表(Style Sheets)
- 深拷贝和浅拷贝
- Orchard模块创建
- Qt之对话框设计——利用QPalette改变控件颜色
- 安装postgreSQL
- IOS PUSH(ios自学笔记)
- SDL_image之hello
- ASP.NET HTMLHELPER