個人理解:
錯誤號呼叫的是同乙個變數,而每個執行緒錯誤時候自己儲存自己的錯誤數字。事實上,全域性存在某種map表(一鍵多值),每次獲取此次的執行緒錯誤,則內部根據執行緒id找到錯誤號。
其中 tsd 為linux下的機制,tls 為windoss下的機制,原理類似。
---------** (感謝其分享)
#include
int pthread_key_create(pthread_key_t *key,void (*destr_function)(void *));
int pthread_setspecific(pthread_key_t key,const void *pointer));
void *pthread_getspecific(pthread_key_t key);
int pthread_key_delete(pthread_key_t key);
key一旦被建立,所有執行緒都可以訪問它,但各執行緒可以根據自己的需要往key中填入不同的值,這就相當於提供了乙個同名而不同值的全域性變數,一鍵多值。一鍵多值靠的是乙個關鍵資料結構陣列,即tsd池其結構如下:
static struct pthread_key_struct pthread_keys[pthread_keys_max] =};
建立乙個tsd就相當於將結構陣列中的某一項設定為「in_use」,並將其索引返回給*key,然後設定destructor函式destr_function。
pthread_setspecific:該函式將pointer的值(不是內容)與key相關聯。用pthread_setspecific為乙個鍵指定新的執行緒資料時,執行緒必須先釋放原有的執行緒資料用以**空間。
pthread_key_delete:該函式用來刪除乙個鍵,鍵所占用的記憶體將被釋放。需要注意的是,鍵占用的記憶體被釋放,與該鍵關聯的執行緒資料所占用的記憶體並不被釋放。因此,執行緒資料的釋放必須在釋放鍵之前完成。
例8-4將實現如何建立和使用執行緒的私有資料,具體**如下所示。
例8-4
#include
#include
#include
pthread_key_t key;
void * thread2(void *arg)
void * thread1(void *arg)
int main(void)
編譯並執行,結果如下:
$ gcc -o 8-4 8-4.c -g -l pthread
$ ./8-4
main thread begins running
thread -1209746544 is running
thread -1218139248 is running
thread -1218139248 returns 5
thread -1209746544 return 0
main thread exit
程式說明:程式中,主線程建立了執行緒thread1,執行緒thread1建立了執行緒thread2。兩個執行緒分別將tsd作為執行緒私有資料。從程式執行結果可以看出,兩個執行緒tsd的修改互不干擾,可以看出thread2先於thread1結束,執行緒在建立thread2後,睡眠3s等待thread2執行完畢。主線程睡眠5s等待thread1結束。可以看出thread2對tsd的修改並沒影響到thread1的tsd的取值。
執行緒特定 私有 資料
簡單的講,執行緒特定 私有 資料是每個執行緒的區域性變數,更改執行緒a中的執行緒特定 私有 資料,並不會影響到執行緒b中相對應的執行緒特定 私有 資料。常見的errno就是執行緒特定 私有 資料,每個執行緒重置errno的操作並不會影響程序中其他執行緒的errno值。下面介紹下執行緒特定資料的使用技...
執行緒的私有資料(TSD)
我們知道 乙個程序內的所有執行緒繼承其資料與環境變數,共享資料空間,但是有時候我們需要有的執行緒擁有獨屬於其自己的資料變數,讓其只在某個執行緒內有效,比如最常見的errno,每個執行緒出錯的原因大不相同。這個時候就需要建立執行緒的私有資料 tsd 了 執行緒的私有資料可以被其他函式訪問,但拒絕被其他...
執行緒控制 私有資料
執行緒私有資料採用了一種被稱為一鍵多值的技術,即乙個鍵對應多個數值。訪問資料時都是通過鍵值來訪問,好像是對乙個變數進行訪問,其實是在訪問不同的資料。使用執行緒私有資料時,首先要為每個執行緒資料建立乙個相關聯的鍵。在各個執行緒內部,都使用這個公用的鍵來指代執行緒資料,但是在不同的執行緒中,這個鍵代表的...