日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

【Linux系统编程】线程私有数据

發布時間:2024/4/24 linux 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Linux系统编程】线程私有数据 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

00. 目錄

文章目錄

    • 00. 目錄
    • 01. 線程之間共享數據
    • 02. 線程私有數據
      • 2.1 創建線程私有數據
      • 2.2 銷毀線程私有數據
      • 2.3 關聯線程私有數據成員
      • 2.4 讀取線程私有數據所關聯的值
    • 03. 案例實踐
    • 04. 附錄

01. 線程之間共享數據

在多線程程序中,經常要用全局變量來實現多個函數間的數據共享。由于數據空間是共享的,因此全局變量也為所有線程共有。

測試代碼:

#include <stdio.h> #include <pthread.h> #include <unistd.h> #include <stdlib.h>int key = 100; //全局變量void *helloworld_one(void *arg) {printf("the message is %s\n",(char *)arg);key = 10;printf("key=%d, the child id is %lu\n", key, pthread_self());return NULL; }void *helloworld_two(void *arg) {printf("the message is %s\n", (char *)arg);sleep(1);printf("key=%d, the child id is %lu\n", key, pthread_self());return NULL; }int main(int argc, char *argv[]) {pthread_t thread_id_one;pthread_t thread_id_two;//創建線程pthread_create(&thread_id_one, NULL, helloworld_one, "helloworld_one");pthread_create(&thread_id_two, NULL, helloworld_two, "helloworld_two");//等待線程結束,回收資源pthread_join(thread_id_one, NULL);pthread_join(thread_id_two, NULL);return 0; }

測試結果:

deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$ gcc 1.c -pthread deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$ ./a.out the message is helloworld_one key=10, the child id is 139954627110656 the message is helloworld_two key=10, the child id is 139954618717952 deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$

由運行結果可以看出,其中一個線程對全局變量的修改將影響到另一個線程的訪問。

02. 線程私有數據

但有時應用程序設計中必要提供線程私有的全局變量,這個變量僅在線程中有效,但卻可以跨過多個函數訪問。比如在程序里可能需要每個線程維護一個鏈表,而會使用相同的函數來操作這個鏈表,最簡單的方法就是使用同名而不同變量地址的線程相關數據結構。這樣的數據結構可以由 Posix 線程庫維護,成為線程私有數據 (Thread-specific Data,或稱為 TSD)。

2.1 創建線程私有數據

int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)); 功能:創建一個類型為 pthread_key_t 類型的私有數據變量( key )。 參數:key:在分配( malloc )線程私有數據之前,需要創建和線程私有數據相關聯的鍵( key ),這個鍵的功能是獲得對線程私有數據的訪問權。destructor:清理函數名字( 如:fun )。當線程退出時,如果線程私有數據地址不是非 NULL,此函數會自動被調用。該函數指針可以設成 NULL ,這樣系統將調用默認的清理函數。回調函數其定義如下:void fun(void *arg){// arg 為 key 值} 返回值:成功:0失敗:非 0

不論哪個線程調用 pthread_key_create(),所創建的 key 都是所有線程可訪問,但各個線程可根據自己的需要往 key 中填入不同的值,相當于提供了一個同名不同值的變量。

2.2 銷毀線程私有數據

int pthread_key_delete(pthread_key_t key); 功能:注銷線程私有數據。這個函數并不會檢查當前是否有線程正使用線程私有數據( key ),也不會調用清理函數 destructor() ,而只是將線程私有數據( key )釋放以供下一次調用pthread_key_create() 使用。 參數:key:待注銷的私有數據。 返回值:成功:0失敗:非 0

2.3 關聯線程私有數據成員

int pthread_setspecific(pthread_key_t key, const void *value); 功能:設置線程私有數據( key ) 和 value 關聯,注意,是 value 的值(不是所指的內容)和 key 相關聯。 參數:key:線程私有數據。value:和 key 相關聯的指針。 返回值:成功:0失敗:非 0

2.4 讀取線程私有數據所關聯的值

void *pthread_getspecific(pthread_key_t key); 功能:讀取線程私有數據( key )所關聯的值。 參數:key:線程私有數據。 返回值:成功:線程私有數據( key )所關聯的值。失敗:NULL

03. 案例實踐

測試程序

// this is the test code for pthread_key #include <stdio.h> #include <pthread.h> pthread_key_t key; // 私有數據,全局變量void echomsg(void *t) { printf("[destructor] thread_id = %lu, param = %p\n", pthread_self(), t); } void *child1(void *arg) { int i = 10;pthread_t tid = pthread_self(); //線程號printf("\nset key value %d in thread %lu\n", i, tid); pthread_setspecific(key, &i); // 設置私有數據printf("thread one sleep 2 until thread two finish\n\n");sleep(2); printf("\nthread %lu returns %d, add is %p\n",tid, *((int *)pthread_getspecific(key)), pthread_getspecific(key) ); } void *child2(void *arg) { int temp = 20;pthread_t tid = pthread_self(); //線程號printf("\nset key value %d in thread %lu\n", temp, tid); pthread_setspecific(key, &temp); //設置私有數據sleep(1); printf("thread %lu returns %d, add is %p\n", tid, *((int *)pthread_getspecific(key)), pthread_getspecific(key)); } int main(void) { pthread_t tid1,tid2; pthread_key_create(&key, echomsg); // 創建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; }

執行結果:

deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$ ./a.out set key value 10 in thread 140551366268672set key value 20 in thread 140551357875968 thread one sleep 2 until thread two finishthread 140551357875968 returns 20, add is 0x7fd4a9c23ecc [destructor] thread_id = 140551357875968, param = 0x7fd4a9c23eccthread 140551366268672 returns 10, add is 0x7fd4aa424ecc [destructor] thread_id = 140551366268672, param = 0x7fd4aa424ecc deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$

從運行結果來看,各線程對自己的私有數據操作互不影響。也就是說,雖然 key 是同名且全局,但訪問的內存空間并不是同一個。

04. 附錄

總結

以上是生活随笔為你收集整理的【Linux系统编程】线程私有数据的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。