1. 程式人生 > >Linux執行緒私有資料pthread_key_t

Linux執行緒私有資料pthread_key_t

#include <pthread.h> 函式原型: int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)); 引數說明: 第一個引數為指向一個鍵值的指標,第二個引數指明瞭一個destructor函式,如果這個引數不為空,那麼當每個執行緒結束時,系統將呼叫這個函式來釋放繫結在這個鍵上的記憶體塊。
函式原型: int pthread_key_delete(pthread_key_t key); 作用: 登出一個TSD,這個函式並不檢查當前是否有執行緒正使用該TSD,也不會呼叫清理函式(destr_function),而只是將TSD釋放以供下一次呼叫pthread_key_create()使用。

int pthread_setspecific(pthread_key_t key,const void *pointer));
void *pthread_getspecific(pthread_key_t key);


set是把一個變數的地址告訴key,一般放在變數定義之後,get會把這個地址讀出來,然後你自己轉義成相應的型別再去操作,注意變數的有效期。只不過,在不同的執行緒裡可以操作同一個key,他們不會衝突,比如執行緒a,b,c set同樣的key,分別get得到的地址會是之前各自傳進去的值。這樣做的意義在於,可以寫一份執行緒程式碼,通過key的方式多執行緒操作不同的資料。

*-----------------------------pthread_private_data.c--------------------------------------*/

/*三個執行緒:主執行緒,th1,th2各自有自己的私有資料區域

*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>

static pthread_key_t str_key;
//define a static variable that only be allocated once
static pthread_once_t str_alloc_key_once=PTHREAD_ONCE_INIT;
staticvoid str_alloc_key();
staticvoid str_alloc_destroy_accu(
void* accu);

char* str_accumulate(constchar* s)
{    char* accu;

    pthread_once(&str_alloc_key_once,str_alloc_key);//str_alloc_key()這個函式只調用一次
    accu=(char*)pthread_getspecific(str_key);//取得該執行緒對應的關鍵字所關聯的私有資料空間首址
if(accu==NULL)//每個新剛建立的執行緒這個值一定是NULL(沒有指向任何已分配的資料空間)
    {    accu=malloc(1024);//用上面取得的值指向新分配的空間
if(accu==NULL)    returnNULL;
        accu[0]=0;//為後面strcat()作準備

        pthread_setspecific(str_key,(void*)accu);//設定該執行緒對應的關鍵字關聯的私有資料空間
        printf("Thread %lx: allocating buffer at %p\n",pthread_self(),accu);
     }
     strcat(accu,s);
return accu;
}
//設定私有資料空間的釋放記憶體函式
staticvoid str_alloc_key()
{    pthread_key_create(&str_key,str_alloc_destroy_accu);/*建立關鍵字及其對應的記憶體釋放函式,當程序建立關鍵字後,這個關鍵字是NULL。之後每建立一個執行緒os都會分給一個對應的關鍵字,關鍵字關聯執行緒私有資料空間首址,初始化時是NULL*/
    printf("Thread %lx: allocated key %d\n",pthread_self(),str_key);
}
/*執行緒退出時釋放私有資料空間,注意主執行緒必須呼叫pthread_exit()(呼叫exit()不行)才能執行該函式釋放accu指向的空間*/
staticvoid str_alloc_destroy_accu(void* accu)
{    printf("Thread %lx: freeing buffer at %p\n",pthread_self(),accu);
    free(accu);
}
//執行緒入口函式
void* process(void *arg)
{    char* res;
    res=str_accumulate("Resule of ");
if(strcmp((char*)arg,"first")==0)
        sleep(3);
    res=str_accumulate((char*)arg);
    res=str_accumulate(" thread");
    printf("Thread %lx\"%s\"\n",pthread_self(),res);
returnNULL;
}
//主執行緒函式
int main(int argc,char* argv[])
{    char* res;
    pthread_t th1,th2;
    res=str_accumulate("Result of ");
    pthread_create(&th1,NULL,process,(void*)"first");
    pthread_create(&th2,NULL,process,(void*)"second");
    res=str_accumulate("initial thread");
    printf("Thread %lx\"%s\"\n",pthread_self(),res);
    pthread_join(th1,NULL);
    pthread_join(th2,NULL);
    pthread_exit(0);

/*------------------------------------------------------------------*/
[[email protected] c]# ./pthread_private_data
Thread b7fdd6c0 : allocated key 0
Thread b7fdd6c0: allocating buffer at 0x911c008
Thread b7fdd6c0: "Result of initial thread"
Thread b7fdcb90: allocating buffer at 0x911c938
Thread b75dbb90: allocating buffer at 0x911cd40
Thread b75dbb90: "Resule of second thread"
Thread b75dbb90: freeing buffer at 0x911cd40
Thread b7fdcb90: "Resule of first thread"
Thread b7fdcb90: freeing buffer at 0x911c938
Thread b7fdd6c0: freeing buffer at 0x911c008

重入函式str_accumulate()裡動態分配記憶體,這些動態分配的空間是執行緒的私有資料,只對本執行緒可見(對主執行緒也不看見)。通過這種技術實現了私有資料的私有分配和回收。(相當於用類的思想實現私有資料的分配和回收,可見執行緒庫向面向物件發展的趨勢是必然的)

相關推薦

Linux執行私有資料pthread_key_t

#include <pthread.h> 函式原型: int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)); 引數說明: 第一個引數為指向一個鍵值的指標,第二個

linux執行私有資料

今天在看執行緒的私有資料時,一直想找個例子,實際的驗證下,用資料告訴自己:"對,就是那樣的,那就是TSD“,於是乎我看到了這個例子 http://www.ibm.com/developerworks/cn/linux/thread/posix_threadapi/part2

linux執行私有資料詳解

    在單執行緒程式中,函式經常使用全域性變數或靜態變數,這是不會影響程式的正確性的,但如果執行緒呼叫的函式使用全域性變數或靜態變數,則很可能引起程式設計錯誤,因為這些函式使用的全域性變數和靜態變數無法為不同的執行緒儲存各自的值,而當同一程序內的不同執行緒幾乎同時呼叫這樣

LinuxLinux執行私有資料

執行緒私有資料 在單執行緒程式中,函式經常使用全域性變數或靜態變數,這是不會影響程式的正確性的,但如果執行緒呼叫的函式使用全域性變數或靜態變數,則很可能引起錯誤。因為這些函式使用的全域性變數和靜態變數無法為不同的執行緒儲存各自的值,而當同一程序內的不同執行緒幾乎同時呼叫這樣

Linux系統程式設計——執行私有資料

在多執行緒程式中,經常要用全域性變數來實現多個函式間的資料共享。由於資料空間是共享的,因此全域性變數也為所有執行緒共有。 測試程式碼如下: #include <stdio.h> #include <pthread.h> #include <unis

linux執行學習筆記六--一次性初始化和執行私有資料

pthread_key_t key; int pthread_key_create(pthread_key *key,void (*destructor)(void*)); int pthread_key_delete(pthread_key_t key); 該函式從TSD池中分配一項,將其值賦給key供以

執行私有資料

    在參考ptmalloc實現的時候,碰到了一個新東西——執行緒私有資料,其資料是這樣宣告的 static tsd_key_t arena_key;。由於ptmalloc中的許多資料結構都是在內部重新定義的,而我手中的這部分原始碼並不是完全的,所以我只好在網上查詢tsd_ke

執行概述、執行控制和執行私有資料

一、執行緒概述   在許多經典的作業系統教科書中,總是把程序定義為程式的執行例項,它並不執行什麼, 只是維護應用程式所需的各種資源,而執行緒則是真正的執行實體。在一個程序中的多個執行路線叫做執行緒。為了

Linux執行資料交換——管道篇

1 管道     最近在做一個有關AD資料採集的專案,有一個採集執行緒,一個數據處理執行緒。為了實現執行緒之間的資料傳輸,我選擇使用管道。然而管道又分為兩種:PIPE和FIFO。參考資料[7]中對這兩種管道進行了對比:PIPE只能在具有公共祖先的程序之間使用,而FIFO則沒

執行私有資料TSD——一鍵多值技術,執行同步中的互斥鎖和條件變數

一:執行緒私有資料: 執行緒是輕量級程序,程序在fork()之後,子程序不繼承父程序的鎖和警告,別的基本上都會繼承,而vfork()與fork()不同的地方在於vfork()之後的程序會共享父程序的地址空間,但是有了寫實複製(fork()之後的子程序也不會直接

執行私有資料STD

概念及作用         在單執行緒程式中,我們經常要用到"全域性變數"以實現多個函式間共享資料。在多執行緒環境下,由於資料空間是共享的,因此全域性變數也為所有執行緒所共有。但有時應用程式設計中有必要提供執行緒私有的全域性變數,僅在某個執行緒中有效,但卻可以跨

UNIX環境高階程式設計——執行私有資料

執行緒私有資料(Thread-specific data,TSD):儲存和查詢與某個執行緒相關資料的一種機制。 1、在程序內的所有執行緒都共享相同的地址空間,即意味著任何宣告為靜態或外部變數,或在程序堆宣告的變數,       都可以被程序內所有的執行緒讀寫。 2、一個

【多執行程式設計】執行私有資料(TSD)

Thread Specific Data(TSD) 執行緒私有資料,有什麼用呢?在多執行緒中,經常要用全域性變數來實現多個函式間的資料共享。由於資料空間是共享的,因此全域性變數也為所有程序共有。但有時應用程式設計中必要提供執行緒私有的全域性變數,這個變數被各個執行緒私有,但

【C/C++多執行程式設計之十】pthread執行私有資料

#include #include #include #include #pragma comment(lib, "pthreadVC2.lib") //必須加上這句 pthread_key_t key; pthread_mutex_t mutex; pthread_t tid1,*p1;

POSIX執行執行私有資料

概念及作用   執行緒私有資料(thread-specify data,TSD)類似於全域性變數,可以跨函式使用,區別是TSD是執行緒私有的。 建立和登出 int pthread_key_create(pthread_key_t *key, void (*destr_func

linux執行私有資料

#include <pthread.h> 函式原型: int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)); 引數說明: 第一個引數為指向一個鍵值的指標,第二個引數指明瞭一個d

《自己動手寫java虛擬機器》學習筆記(七)-----執行私有執行資料區(go)

     專案地址:https://github.com/gongxianshengjiadexiaohuihui      在執行java程式時,Java虛擬機器需要使用記憶體來存放各種各樣的資料,Java虛擬機器規範把這些記憶體的區

Linux執行特定資料

概述 執行緒特定資料(執行緒私有資料)是儲存和查詢某個特定執行緒相關資料的一種機制,使用這種機制是因為我們希望每個執行緒可以訪問它自己單獨的資料副本,而不需要擔心與其他執行緒的訪問同步問題。 執行緒的好處就在於促進了程序中資料和屬性的共享,那麼設計執行緒私有

Linux執行---執行特定資料

在單執行緒程式中。我們常常要用到”全域性變數”以實現多個函式間共享資料, 然而在多執行緒環境下。因為資料空間是共享的。因此全域性變數也為全部執行緒所共同擁有。但有時應用程式設計中有必要提供執行緒私有的全域性變數,僅在某個執行緒中有效,但卻能夠跨多個函式訪問。PO

Linux執行接收資料,子執行分別對其操作後輸出

本例子雖小,但是融合的執行緒同步,執行緒回收和訊號量的知識。 需要注意pthread_join()和pthread_exit()的用法和區別: pthread_join一般是主執行緒來呼叫,用來等待子執行緒退出,因為是等待,所以是阻塞的,一般主執行緒會依次join所有它建立