多線程並發調用文件複製接口,每線程需獨立緩存區。若用全局 static 緩存,多線程數據污染;若每次分配釋放,內存碎片嚴重。TLS 完美解決:線程創建時分配緩存,線程結束自動釋放,僅對當前線程可見。
pthread_key_create(&key, destructor):創建 TLS 鍵,可指定析構函數pthread_setspecific(key, value):綁定線程私有數據pthread_getspecific(key):獲取當前線程私有數據pthread_key_delete(key):銷毀鍵(不調用析構函數)
#include <iostream>
#include <pthread.h>
#include <windows.h>
#include <stdio.h>
typedef enum {
kTLSKeyCopyFileBuf = 0,
kTLSKeyOthers,
kTLSKeyMax
} kTLSKey;
static pthread_key_t gTLSKey[kTLSKeyMax];
static int gTLSKeySize[kTLSKeyMax] = {4194304, 4096}; // 4MB, 4KB
static pthread_barrier_t barrier;
static int THREADCOUNT = 10;
// 庫接口 1:初始化 TLS 鍵
void StartWork(kTLSKey type) {
pthread_key_create(&gTLSKey[type], NULL);
}
// 庫接口 2:銷毀 TLS 鍵
void EndWork(kTLSKey type) {
pthread_key_delete(gTLSKey[type]);
}
// 庫接口 3:文件複製(演示 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); // 驗證 TLS 隔離性
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); // 綁定到當前線程
// 每線程複製 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 主線程
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() {
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 ...(10 個線程各自分配獨立 4MB 緩存,地址互不相同) ThreadFunc: 5168 finish ThreadFunc: 3892 finish ... end thread local storage.
每線程緩存地址唯一,驗證了 TLS 隔離性。線程結束自動釋放(此處手動 free,實際可用析構函數自動管理)。
TlsAlloc/TlsFree/TlsSetValue/TlsGetValue:Windows API,功能類似__declspec(thread):編譯期 TLS,僅支持 POD 類型,不支持動態初始化malloc 綁定,線程退出前 free(或註冊析構函數)