1. 程式人生 > >linux下C語言多執行緒(二)執行緒的私有資料

linux下C語言多執行緒(二)執行緒的私有資料

二. 建立和登出
Posix定義了兩個API分別用來建立和登出TSD:

int pthread_key_create(pthread_key_t *key, void (*destr_function) (void *));

該函式從TSD池中分配一項,將其值賦給key供以後訪問使用。如果destr_function不為空,線上程退出(pthread_exit())時將以key所關聯的資料為引數呼叫destr_function(),以釋放分配的緩衝區。

不論哪個執行緒呼叫pthread_key_create(),所建立的key都是所有執行緒可訪問的,但各個執行緒可根據自己的需要往key中填入不同的值,這就相當於提供了一個同名而不同值的全域性變數。在LinuxThreads的實現中,TSD池用一個結構陣列表示:

static struct pthread_key_struct pthread_keys[PTHREAD_KEYS_MAX] = { { 0, NULL } };

建立一個TSD就相當於將結構陣列中的某一項設定為"in_use",並將其索引返回給*key,然後設定destructor函式為destr_function。

登出一個TSD採用如下API:

int pthread_key_delete(pthread_key_t key);

這個函式並不檢查當前是否有執行緒正使用該TSD,也不會呼叫清理函式(destr_function),而只是將TSD釋放以供下一次呼叫pthread_key_create()使用。在LinuxThreads中,它還會將與之相關的執行緒資料項設為NULL(見"訪問")。

三. 訪問
TSD的讀寫都通過專門的Posix Thread函式進行,其API定義如下:
int pthread_setspecific(pthread_key_t key, const void *pointer);
void * pthread_getspecific(pthread_key_t key) ;

寫入(pthread_setspecific())時,將pointer的值(不是所指的內容)與key相關聯,而相應的讀出函式則將與key相關聯的資料讀出來。資料型別都設為void *,因此可以指向任何型別的資料。
在LinuxThreads中,使用了一個位於執行緒描述結構(_pthread_descr_struct)中的二維void *指標陣列來存放與key關聯的資料,陣列大小由以下幾個巨集來說明: