執行緒特定資料TSD及其實現原理
引言:
單執行緒C程式有兩類基本資料:區域性資料和全域性資料。對於多執行緒C程式,添加了第三類資料:執行緒特定資料
那麼為什麼要引入執行緒特定資料呢?試想如果你的一個執行緒裡面巢狀呼叫了很多函式,而你又想在這些函式之間使用一個
公共的變數,如果在單執行緒C中,我們是不是就要宣告一個全域性變量了呢?是的。但是我們想使宣告的這個全域性變數
只屬於我們當前這個例項執行緒(同一個void *(*start_routine)(void *)可以例項化很多執行緒),其他的執行緒訪問不到,
故引入執行緒特定資料TSD。(ps:如果我們直接聲明瞭一個全域性變數,則其他執行緒也有可能使用到這個變數)。
執行緒特定資料:
執行緒特定資料與全域性資料非常相似,區別在於前者為執行緒所有。(如果你學過面向物件程式設計,他們的關係就類似於
class中靜態成員與普通成員的關係。所有物件都可以訪問靜態成員,而每個普通物件的普通成員只能被自己這個物件
訪問)
實現:
每一個系統支援的TSD限制都不一樣。POSIX要求系統至少支援128個TSD,系統為每一個程序維護了一個稱之為
Key的資料結構陣列。如下圖每個TSD包含兩項內容:使用標誌和解構函式指標。標誌:這個陣列元素是否正在使用當一個
執行緒呼叫pthread_key_create建立一個新的TSD時,系統會搜尋key結構陣列,找出其中一個未使用的元素,並通過key返
回該元素的鍵,即我們前面所說的索引。pthread_key_create函式的第二個引數destructor是一個函式指標,指向一個析構
函式,用於執行緒結束後一些後期處理。解構函式的引數就是指向TSD的指標
除了程序範圍內的key結構陣列外,系統還在程序中維護關於每個執行緒的執行緒結構,把這個特定於執行緒的結構稱為pthread
結構,它的128個指標和程序中的128個可能的鍵是逐一關聯的。指標指向的記憶體就是TSD。兩者之間關係如下