進程內的全部線程共享進程的數據空間,因此全局變量爲全部線程共有。在某些場景下,線程須要保存本身的私有數據,這時能夠建立線程私有數據(Thread-specific Data)TSD來解決。在線程內部,私有數據能夠被線程的各個接口訪問,但對其餘線程屏蔽。linux
線程私有數據採用了一鍵多值技術,及一個key對應多個值。訪問數據都是經過鍵值來訪問的。數組
使用線程私有數據時,須要對每一個線程建立一個關聯 的key,linux中主要有四個接口來實現:app
一、pthread_key_create:建立一個鍵函數
int pthread_key_create(pthread_key_t *key, void (*destr_function) (void*));
首先從linux的TSD池中分配一項,而後將其值賦給key供之後訪問使用。接口的第一個參數是指向參數的指針,第二參數是函數指針,若是該指針不爲空,那麼在線程執行完畢退出時,已key指向的內容爲入參調用destr_function(),釋放分配的緩衝區以及其餘數據。ui
key被建立以後,由於是全局變量,因此全部的線程均可以訪問。各個線程能夠根據需求往key中,填入不一樣的值,這就至關於提供了一個同名而值不一樣的全局變量,即一鍵多值。一鍵多值依靠的一個結構體數組,即spa
static struct pthread_key_struct pthread_keys[PTHREAD_KEYS_MAX] ={{0,NULL}};
pthread_key_struct 的定義爲:線程
struct pthread_key_struct { /* Sequence numbers. Even numbers indicated vacant entries. Note that zero is even. We use uintptr_t to not require padding on 32- and 64-bit machines. On 64-bit machines it helps to avoid wrapping, too. */ uintptr_t seq; /* Destructor for the data. */ void (*destr) (void *); };
PTHREAD_KEYS_MAX值爲1024指針
建立一個TSD,至關於將結構體數組的某一個元素的seq值設置爲爲「in_use」,並將其索引返回給*key,而後設置destr_function()爲destr()。pthread_key_create建立一個新的線程私有數據key時,系統會搜索其所在進程的key結構數組,找出一個未使用的元素,將其索引賦給*key。code
二、pthread_setspecific:爲指定鍵值設置線程私有數據blog
int pthread_setspecific(pthread_key_t key, const void *pointer);
該接口將指針pointer的值(指針值而非其指向的內容)與key相關聯,用pthread_setspecific爲一個鍵指定新的線程數據時,線程必須釋放原有的數據用以回收空間。
三、pthread_getspecific:從指定鍵讀取線程的私有數據
void * pthread_getspecific(pthread_key_t key);
四、pthread_key_delete:刪除一個鍵
void * pthread_getspecific(pthread_key_t key);
該接口用於刪除一個鍵,功能僅僅是將該key在結構體數組pthread_keys對應的元素設置爲「un_use」,與改key相關聯的線程數據是不會被釋放的,所以線程私有數據的釋放必須在鍵刪除以前。