線程安全問題
線程安全問題是一個非常復雜的問題。簡單地說范舀,就是多個線程在操作共享數(shù)據(jù)時出現(xiàn)的混亂情況,這種情況可能導致不可預測的后果厨诸。
解決線程安全問題的方法主要有兩種:一是使用線程安全函數(shù):posix定義的以”_r”結尾的函數(shù),二是使用線程專用數(shù)據(jù)(TSD)禾酱。
線程專用數(shù)據(jù):TSD
在多線程環(huán)境中微酬,應避免使用靜態(tài)變量。在linux環(huán)境中颤陶,用線程專用數(shù)據(jù)TSD取代靜態(tài)變量颗管。它類似于全局數(shù)據(jù),只不過它是線程私有的指郁,是以線程為界限的忙上。TSD是定義線程私有全局數(shù)據(jù)的唯一方法拷呆。
每個TSD由進程內(nèi)唯一的關鍵字(key)來標識闲坎,用這個關鍵字,線程可以存取線程私有的數(shù)據(jù)茬斧。
pthread_key_create函數(shù)
#include <pthread.h>
int pthread_key_create(pthread_key_t *key, void (* destructor)(void *value));
? ? ? ? 返回值:正常執(zhí)行后返回0腰懂,否則返回錯誤碼
在進程中分配一個鍵字,關鍵字是進程內(nèi)部唯一的项秉,用來標識一個線程專用數(shù)據(jù)項(每個線程專用數(shù)據(jù)和這個關鍵字關聯(lián))绣溜。這個鍵對進程中所有的線程都是可見的。剛創(chuàng)建線程娄蔼,在所有線程中和這個鍵相關聯(lián)的值都是NULL
創(chuàng)建鍵之后怖喻,每個線程都會將一個值(線程專用數(shù)據(jù)TSD)綁定到該鍵底哗。這些值特定于線程并且針對每個線程單獨維護。
key指向創(chuàng)建的關鍵字锚沸;destructor是一個可選的析構函數(shù)跋选,用于每個線程終止時調(diào)用該析構函數(shù),釋放線程綁定(關聯(lián))在該鍵上得內(nèi)存塊哗蜈。當線程結束時并且將非空的值綁定(關聯(lián))在這個鍵上前标,系統(tǒng)將調(diào)用destructor函數(shù),參數(shù)就是相關線程與這個鍵綁定的值距潘。綁定在這個鍵上的內(nèi)存塊可由destructor函數(shù)釋放炼列。
pthread_setspecific函數(shù)
#include <pthread.h>
int pthread_setspecific(pthread_key_t key, const void *value);
? ? ? ? 返回值:正常執(zhí)行后返回0;否則返回正的錯誤碼
該函數(shù)為TSD關鍵字綁定(關聯(lián))一個與本線程相關的值音比;
void * pthread_getspecific(pthread_key_t key);
? ? 返回值:正常執(zhí)行后返回與調(diào)用線程相關的關鍵字所綁定(關聯(lián))的值俭尖,否則返回NULL。
該函數(shù)獲得與調(diào)用線程相關的關鍵字所綁定的值硅确。
pthread_key_delete函數(shù)
int pthread_key_delete(pthread_key_t key);
返回值:成功為0目溉,否則為非0;
該函數(shù)刪除進程內(nèi)的TSD表示的關鍵字菱农。該函數(shù)既不檢查TSD是否有綁定值缭付,也不調(diào)用該關鍵字的析構函數(shù)