文章來(lái)源自pthread_key_t和pthread_key_create()詳解
下面說(shuō)一下線程中特有的線程存儲(chǔ), Thread Specific Data
。線程存儲(chǔ)有什么用了?他是什么意思了?大家都知道,在多線程程序中,所有線程共享程序中的變量。現(xiàn)在有一全局變量,所有線程都可以使用它,改變它的值。而如果每個(gè)線程希望能單獨(dú)擁有它,那么就需要使用線程存儲(chǔ)了。表面上看起來(lái)這是一個(gè)全局變量,所有線程都可以使用它,而它的值在每一個(gè)線程中又是單獨(dú)存儲(chǔ)的。這就是線程存儲(chǔ)的意義。
下面說(shuō)一下線程存儲(chǔ)的具體用法。
創(chuàng)建一個(gè)類型為
pthread_key_t
類型的變量。調(diào)用
pthread_key_create()
來(lái)創(chuàng)建該變量。該函數(shù)有兩個(gè)參數(shù),第一個(gè)參數(shù)就是上面聲明的pthread_key_t
變量,第二個(gè)參數(shù)是一個(gè)清理函數(shù),用來(lái)在線程釋放該線程存儲(chǔ)的時(shí)候被調(diào)用。該函數(shù)指針可以設(shè)成NULL
,這樣系統(tǒng)將調(diào)用默認(rèn)的清理函數(shù)。該函數(shù)成功返回0.其他任何返回值都表示出現(xiàn)了錯(cuò)誤。當(dāng)線程中需要存儲(chǔ)特殊值的時(shí)候,可以調(diào)用
pthread_setspcific()
。該函數(shù)有兩個(gè)參數(shù),第一個(gè)為前面聲明的pthread_key_t
變量,第二個(gè)為void*
變量,這樣你可以存儲(chǔ)任何類型的值。如果需要取出所存儲(chǔ)的值,調(diào)用
pthread_getspecific()
。該函數(shù)的參數(shù)為前面提到的pthread_key_t
變量,該函數(shù)返回void *
類型的值。下面是前面提到的函數(shù)的原型:
int pthread_setspecific(pthread_key_t key, const void *value);
void *pthread_getspecific(pthread_key_t key);
int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
下面是一個(gè)如何使用線程存儲(chǔ)的例子:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
pthread_key_t key; // 好吧,這個(gè)玩意究竟是干什么的呢?
struct test_struct { // 用于測(cè)試的結(jié)構(gòu)
int i;
float k;
};
void *child1(void *arg)
{
struct test_struct struct_data; // 首先構(gòu)建一個(gè)新的結(jié)構(gòu)
struct_data.i = 10;
struct_data.k = 3.1415;
pthread_setspecific(key, &struct_data); // 設(shè)置對(duì)應(yīng)的東西嗎?
printf("child1--address of struct_data is --> 0x%p\n", &(struct_data));
printf("child1--from pthread_getspecific(key) get the pointer and it points to --> 0x%p\n", (struct test_struct *)pthread_getspecific(key));
printf("child1--from pthread_getspecific(key) get the pointer and print it's content:\nstruct_data.i:%d\nstruct_data.k: %f\n",
((struct test_struct *)pthread_getspecific(key))->i, ((struct test_struct *)pthread_getspecific(key))->k);
printf("------------------------------------------------------\n");
}
void *child2(void *arg)
{
int temp = 20;
sleep(2);
printf("child2--temp's address is 0x%p\n", &temp);
pthread_setspecific(key, &temp); // 好吧,原來(lái)這個(gè)函數(shù)這么簡(jiǎn)單
printf("child2--from pthread_getspecific(key) get the pointer and it points to --> 0x%p\n", (int *)pthread_getspecific(key));
printf("child2--from pthread_getspecific(key) get the pointer and print it's content --> temp:%d\n", *((int *)pthread_getspecific(key)));
}
int main(void)
{
pthread_t tid1, tid2;
pthread_key_create(&key, NULL); // 這里是構(gòu)建一個(gè)pthread_key_t類型,確實(shí)是相當(dāng)于一個(gè)key
pthread_create(&tid1, NULL, child1, NULL);
pthread_create(&tid2, NULL, child2, NULL);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
pthread_key_delete(key);
return (0);
}
看一下輸出的結(jié)果:
child1--address of struct_data is --> 0x0x7ffff77eff40
child1--from pthread_getspecific(key) get the pointer and it points to --> 0x0x7ffff77eff40
child1--from pthread_getspecific(key) get the pointer and print it's content:
struct_data.i:10
struct_data.k: 3.141500
------------------------------------------------------
child2--temp's address is 0x0x7ffff6feef44
child2--from pthread_getspecific(key) get the pointer and it points to --> 0x0x7ffff6feef44
child2--from pthread_getspecific(key) get the pointer and print it's content --> temp:20
非常有意思呢。