執行緒特定資料,也稱為執行緒私有資料,是儲存和查詢某個特定資料相關資料的一種機制。
在單執行緒程式中,我們經常要用到「全域性變數」以實現多個函式間共享資料。
在多執行緒環境下,由於資料空間是共享的,因此全域性變數也為所有所有執行緒所共有。
但有時應用程式設計中有必要提供執行緒私有的全域性變數,僅在某個執行緒中有效,但卻可以跨多個函式訪問。
posix執行緒庫通過維護一定的資料結構來解決這個問題,這些資料被稱為執行緒特定資料(thread-specific data,或tsd)。
在分配執行緒特定資料之前,需要建立與該資料關聯的鍵。這個鍵將用於獲取對執行緒特定資料的訪問。使用pthread_key_create函式建立乙個鍵。
int pthread_key_create(pthread_key_t *key, void (*destr_function) (void*));
除了建立鍵以外,pthread_key_create可以為該鍵關聯乙個可選擇的析構函式。當這個執行緒退出時,如果資料位址已經被置為非空值,那麼析構函式就會被呼叫,它唯一的引數就是該資料位址。如果傳入的析構函式為空,就表明沒有析構函式與這個鍵關聯。
執行緒通常使用malloc為執行緒特定資料分配記憶體。析構函式通常釋放已分配的記憶體。
對所有的執行緒,我們都可以通過呼叫pthread_key_delete函式來取消鍵與執行緒特定資料值之間的聯絡。
int pthread_key_delete(pthread_key_t key);
有些執行緒可能看到乙個鍵值,而其他的執行緒看到的可能是另乙個不同的鍵值,這取決於系統是如何排程執行緒的,解決這種競爭的辦法是使用pthread_once函式 。
pthread_once_t once_control = pthread_once_init;
int pthread_once(pthread_once_t *once_control, void (*init_routine)
(void));
once_control必須是乙個非本地變數(如全域性變數或靜態變數),而且必須初始化為pthread_once_init。如果每個執行緒都呼叫pthread_once,系統就能保證初始化once_control只被呼叫一次,即系統首次呼叫pthread_once時。
鍵一旦建立以後,就可以通過呼叫pthread_setspecific函式把鍵和執行緒特定資料關聯起來。可以通過pthread_getspecific獲得執行緒特定資料的位址。
int pthread_setspecific(pthread_key_t key, const void *pointer);
void * pthread_getspecific(pthread_key_t key);
如果沒有執行緒特定資料值與鍵關聯,pthread_getspecific將返回乙個空指標,我們可以用這個空指標確定是否需要呼叫pthread_setspecific。
注:參考unix高階環境程式設計(第三版)
#include #include #include #include #include #include #include #define err_exit(m) \
do \
while(0); \
//自定義執行緒資料
執行緒特定資料
執行緒特定資料也稱執行緒私有資料,是儲存和查詢某個特定執行緒相關資料的一種機制。在分配執行緒特定資料之前,需要建立與該資料相關聯的鍵,以用於獲取對執行緒特定資料的訪問。使用函式 pthread key create 可建立乙個鍵,而對所有的執行緒,都可以通過 pthread key delete 來...
Linux執行緒 執行緒特定資料
在單執行緒程式中。我們常常要用到 全域性變數 以實現多個函式間共享資料,然而在多執行緒環境下。因為資料空間是共享的。因此全域性變數也為全部執行緒所共同擁有。但有時應用程式設計中有必要提供執行緒私有的全域性變數,僅在某個執行緒中有效,但卻能夠跨多個函式訪問。posix執行緒庫通過維護一定的資料結構來解...
執行緒特定資料(學習)
1 首先,為什麼要使用執行緒特定資料呢?什麼是執行緒特定資料。這牽涉到重入函式和不可重入函式。重入函式就是在多個程序或者執行緒中,可以同時進行執行的函式,可重入函式就是不可以同時執行的函式,這個主要是可能多個程序或執行緒共享了乙個變數,這個變數只有乙個,這樣同時執行的時候,就會出問題了,因為我們不知...