标签:tls 线程本地变量 pthread win32 pthread_key_t
使用场景:
1. 在复制文件时,一般都是一个线程调用一个接口复制文件,这时候需要缓存数据,如果每个文件都需要创建独立的缓存,那么内存碎片是很大的.
如果创建一个static的内存区,当多线程调用同一个接口时,多个线程同时使用同一个static缓存会造成数据污染.最好的办法是这个缓存只对这个线程可见,
当线程创建时创建缓存区,当线程结束时销毁缓存区.
2. 代码里有注释:
test.cpp
#include <iostream> #include "pthread.h" #include <assert.h> #include <Windows.h> #include <stdio.h> typedef enum kTLSKey1 { kTLSKeyCopyFileBuf = 0, kTLSKeyOthers, kTLSKeyMax }kTLSKey; static pthread_key_t gTLSKey[kTLSKeyMax]; static int gTLSKeySize[kTLSKeyMax] = {4194304,4096}; // 这个只是测试等待线程全部结束用的,和TLS没什么关系. static pthread_barrier_t barrier = NULL; static int THREADCOUNT = 10; // 我们自定义的库提供的接口1 void StartWork(kTLSKey type) { pthread_key_t& key = gTLSKey[type]; pthread_key_create(&key,NULL); } // 我们自定义的库提供的接口2 void EndWork(kTLSKey type) { pthread_key_t& key = gTLSKey[type]; pthread_key_delete(key); } // 我们自定义的库提供的接口3 // data参数只是为了证明TLS的变量是绑定线程的. void MyCopyFile(const char* from, const char* to,void* data) { pthread_key_t& key = gTLSKey[kTLSKeyCopyFileBuf]; char* lpvData = (char*)pthread_getspecific(key); assert(lpvData == data); Sleep(100); } void* ThreadFunc(void* data) { int size = gTLSKeySize[kTLSKeyCopyFileBuf]; pthread_key_t& key = gTLSKey[kTLSKeyCopyFileBuf]; char* buf = (char*)malloc(size); std::cout << GetCurrentThreadId() <<" Create buf size: " << size << ":" << (int*)buf << std::endl; pthread_setspecific(key, buf); // 申请的内存存放到TLS里. // 每个线程复制100个文件 for (int i = 0; i < 100; ++i) { MyCopyFile("C:\\infoworld.txt","E:\\infoworld.txt",buf); } free(buf); std::cout << "ThreadFunc: " << GetCurrentThreadId() << " finish" << std::endl; pthread_barrier_wait(&barrier); return NULL; } void TestPthreadLocalStorage() { StartWork(kTLSKeyCopyFileBuf); // 在主程序初始化. pthread_barrier_init(&barrier,NULL, THREADCOUNT+1); // 主线程也是,所以+1 // 模拟 THREADCOUNT 个线程同时调用接口 MyCopyFile. for (int i = 0; i < THREADCOUNT; ++i) { pthread_t t; pthread_create(&t,NULL,ThreadFunc,NULL); pthread_detach(t); } pthread_barrier_wait(&barrier); EndWork(kTLSKeyCopyFileBuf); // 在主程序释放. } int main(int argc, char const *argv[]) { setvbuf(stdout,NULL,_IONBF,0); std::cout << "test thread local storage." << std::endl; TestPthreadLocalStorage(); std::cout << "end thread local storage." << std::endl; return 0; }
输出:
test thread local storage. 5168 Create buf size: 4194304:0x1180020 3892 Create buf size: 4194304:0x1790020 3352 Create buf size: 4194304:0x21a0020 5808 Create buf size: 4194304:0x29b0020 4972 Create buf size: 4194304:0x2dc0020 6812 Create buf size: 4194304:0x31d0020 6132 Create buf size: 4194304:52200x35e0020 Create buf size: 4194304:0x39f0020 6124 Create buf size: 4194304:0x3e00020 6864 Create buf size: 4194304:0x4210020 ThreadFunc: 5168 finish ThreadFunc: 3892 finish ThreadFunc: 6812 finish ThreadFunc: 5220 finish ThreadFunc: 4972 finish ThreadFunc: 6132 finish ThreadFunc: 6864 finish ThreadFunc: 3352 finish ThreadFunc: 5808 finish ThreadFunc: 6124 finish end thread local storage.
http://download.csdn.net/detail/infoworld/9251421
版权声明:本文为博主原创文章,未经博主允许不得转载。
[并发并行]_[C/C++]_[使用线程本地存储Thread Local Storage(TLS)调用复制文件接口的案例]
标签:tls 线程本地变量 pthread win32 pthread_key_t
原文地址:http://blog.csdn.net/infoworld/article/details/49715355