pthread_key_t和pthread_key_create()詳解

文章來源自pthread_key_t和pthread_key_create()詳解

下面說一下線程中特有的線程存儲, Thread Specific Data 。線程存儲有什么用了?他是什么意思了?大家都知道,在多線程程序中,所有線程共享程序中的變量。現在有一全局變量,所有線程都可以使用它,改變它的值。而如果每個線程希望能單獨擁有它,那么就需要使用線程存儲了。表面上看起來這是一個全局變量,所有線程都可以使用它,而它的值在每一個線程中又是單獨存儲的。這就是線程存儲的意義。

下面說一下線程存儲的具體用法。

  1. 創建一個類型為pthread_key_t類型的變量。

  2. 調用pthread_key_create()來創建該變量。該函數有兩個參數,第一個參數就是上面聲明的pthread_key_t變量,第二個參數是一個清理函數,用來在線程釋放該線程存儲的時候被調用。該函數指針可以設成 NULL,這樣系統將調用默認的清理函數。該函數成功返回0.其他任何返回值都表示出現了錯誤。

  3. 當線程中需要存儲特殊值的時候,可以調用 pthread_setspcific() 。該函數有兩個參數,第一個為前面聲明的pthread_key_t變量,第二個為void*變量,這樣你可以存儲任何類型的值。

  4. 如果需要取出所存儲的值,調用pthread_getspecific()。該函數的參數為前面提到的pthread_key_t變量,該函數返回void *類型的值。下面是前面提到的函數的原型:

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*));

下面是一個如何使用線程存儲的例子:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

pthread_key_t key; // 好吧,這個玩意究竟是干什么的呢?

struct test_struct { // 用于測試的結構
    int i;
    float k;
};

void *child1(void *arg)
{
    struct test_struct struct_data; // 首先構建一個新的結構
    struct_data.i = 10;
    struct_data.k = 3.1415;
    pthread_setspecific(key, &struct_data); // 設置對應的東西嗎?
    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); // 好吧,原來這個函數這么簡單
    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); // 這里是構建一個pthread_key_t類型,確實是相當于一個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);
}

看一下輸出的結果:

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

非常有意思呢。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 轉自:Youtherhttps://www.cnblogs.com/youtherhome/archive/201...
    njukay閱讀 1,633評論 0 52
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,981評論 19 139
  • 簡介 線程創建 線程屬性設置 線程參數傳遞 線程優先級 線程的數據處理 線程的分離狀態 互斥鎖 信號量 一 線程創...
    第八區閱讀 8,591評論 1 6
  • 轉至元數據結尾創建: 董瀟偉,最新修改于: 十二月 23, 2016 轉至元數據起始第一章:isa和Class一....
    40c0490e5268閱讀 1,776評論 0 9
  • 又是一個夏天,又是一年高考時。不知為何每年一到這個時候我總是會莫名的情緒低落與煩躁。 如今QQ使用的...
    低眉斂靜閱讀 199評論 0 0