進(jìn)程內(nèi)的所有線程共享進(jìn)程的數(shù)據(jù)空間,所以全局變量為所有線程共有。在某些場景下,線程需要保存自己的私有數(shù)據(jù),這時(shí)可以創(chuàng)建線程私有數(shù)據(jù)(Thread-specific Data)TSD來解決。在線程內(nèi)部,私有數(shù)據(jù)可以被線程的各個(gè)接口訪問,但對其他線程屏蔽。
線程私有數(shù)據(jù)采用了一鍵多值技術(shù),及一個(gè)key對應(yīng)多個(gè)值。訪問數(shù)據(jù)都是通過鍵值來訪問的。
使用線程私有數(shù)據(jù)時(shí),需要對每個(gè)線程創(chuàng)建一個(gè)關(guān)聯(lián) 的key,linux中主要有四個(gè)接口來實(shí)現(xiàn):
1、pthread_key_create:創(chuàng)建一個(gè)鍵
int pthread_key_create(pthread_key_t *key, void (*destr_function) (void*));
首先從linux的TSD池中分配一項(xiàng),然后將其值賦給key供以后訪問使用。接口的第一個(gè)參數(shù)是指向參數(shù)的指針,第二參數(shù)是函數(shù)指針,如果該指針不為空,那么在線程執(zhí)行完畢退出時(shí),已key指向的內(nèi)容為入?yún)⒄{(diào)用destr_function(),釋放分配的緩沖區(qū)以及其他數(shù)據(jù)。
key被創(chuàng)建之后,因?yàn)槭侨肿兞浚运械木€程都可以訪問。各個(gè)線程可以根據(jù)需求往key中,填入不同的值,這就相當(dāng)于提供了一個(gè)同名而值不同的全局變量,即一鍵多值。一鍵多值依靠的一個(gè)結(jié)構(gòu)體數(shù)組,即
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
創(chuàng)建一個(gè)TSD,相當(dāng)于將結(jié)構(gòu)體數(shù)組的某一個(gè)元素的seq值設(shè)置為為“in_use”,并將其索引返回給*key,然后設(shè)置destr_function()為destr()。pthread_key_create創(chuàng)建一個(gè)新的線程私有數(shù)據(jù)key時(shí),系統(tǒng)會(huì)搜索其所在進(jìn)程的key結(jié)構(gòu)數(shù)組,找出一個(gè)未使用的元素,將其索引賦給*key。
2、pthread_setspecific:為指定鍵值設(shè)置線程私有數(shù)據(jù)
int pthread_setspecific(pthread_key_t key, const void *pointer);
該接口將指針pointer的值(指針值而非其指向的內(nèi)容)與key相關(guān)聯(lián),用pthread_setspecific為一個(gè)鍵指定新的線程數(shù)據(jù)時(shí),線程必須釋放原有的數(shù)據(jù)用以回收空間。
3、pthread_getspecific:從指定鍵讀取線程的私有數(shù)據(jù)
void * pthread_getspecific(pthread_key_t key);
4、pthread_key_delete:刪除一個(gè)鍵
void * pthread_getspecific(pthread_key_t key);
該接口用于刪除一個(gè)鍵,功能僅僅是將該key在結(jié)構(gòu)體數(shù)組pthread_keys對應(yīng)的元素設(shè)置為“un_use”,與改key相關(guān)聯(lián)的線程數(shù)據(jù)是不會(huì)被釋放的,因此線程私有數(shù)據(jù)的釋放必須在鍵刪除之前。
新聞熱點(diǎn)
疑難解答
圖片精選