Linux執行緒---執行緒特定資料
阿新 • • 發佈:2019-01-01
在單執行緒程式中。我們常常要用到”全域性變數”以實現多個函式間共享資料, 然而在多執行緒環境下。因為資料空間是共享的。因此全域性變數也為全部執行緒所共同擁有。但有時應用程式設計中有必要提供執行緒私有的全域性變數,僅在某個執行緒中有效,但卻能夠跨多個函式訪問。POSIX執行緒庫通過維護一定的資料結構來解決問題。這個些資料稱為(Thread-specific-data或 TSD)。
#include <stdio.h>
#include <pthread.h>
#include <malloc.h>
#include <unistd.h>
pthread_key_t key;
pthread_once_t once_control = PTHREAD_ONCE_INIT;
typedef struct tsd
{
pthread_t id;
char *val;
}Tsd;
void destructor(void *value)
{
free(value);
printf("destructor\n");
}
// 只執行一次
void init()
{
// 分配用於標識程序中執行緒特定資料的鍵
// 鍵對程序中的所有執行緒來說是全域性的
// 建立執行緒特定資料時,所有執行緒最初都具有與該鍵關聯的NULL值
// 使用可選的解構函式destructor可以釋放過時的儲存
pthread_key_create(&key, (void *)destructor);
printf("init\n");
}
void thread(void *arg)
{
// 初始化執行緒
// 首次呼叫pthread_once時呼叫初始化例程
// 以後呼叫pthread_once()將不起作用
pthread_once(&once_control, init);
// 設定執行緒特定資料
Tsd *t = (Tsd*)malloc(sizeof(Tsd));
t->id = pthread_self();
t->val = (char*)arg;
pthread_setspecific(key, t); // 為指定執行緒特定資料鍵設定執行緒特定繫結
printf("%s setspecific\n", (char*)arg);
// 獲取執行緒特定資料
t = (Tsd*)pthread_getspecific(key); // 獲取呼叫執行緒的鍵繫結,並將該繫結儲存在返回指標指向的位置中
printf("id=0x%x, val=%s\n", (unsigned int)t->id, (char*)t->val);
usleep(1000);
// 再次獲取執行緒特定資料
t = (Tsd*)pthread_getspecific(key);
printf("id=0x%x, val=%s\n", (unsigned int)t->id, (char*)t->val);
pthread_exit(0);
}
int main()
{
pthread_t t1, t2;
pthread_create(&t1, NULL, (void*)thread, (void*)"string1");
pthread_create(&t2, NULL, (void*)thread, (void*)"string2");
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_key_delete(key);
return 0;
}