<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 134,comments - 22,trackbacks - 0
     在多線程環境下,進程內的所有線程共享進程的數據空間,因此全局變量為所有線程共有。在程序設計中有時需要保存線程自己的全局變量,這種特殊的變量僅在某個線程內部有效。如常見的變量errno,它返回標準的出錯代碼。errno不應該是一個局部變量,幾乎每個函數都應該可以訪問它;但它又不能作為一個全局變量,否則在一個線程里輸出的很可能是另一個線程的出錯信息,這個問題可以通過創建線程的私有數據(Thread-specific Data,或TSD)來解決。在線程內部,線程私有數據可以被各個函數訪問,但它對其他線程是屏蔽的。
        線程私有數據采用了一種被稱為一鍵多值的技術,即一個鍵對應多個數值。訪問數據時都是通過鍵值來訪問,好像是對一個變量進行訪問,其實是在訪問不同的數據。使用線程私有數據時,首先要為每個線程數據創建一個相關聯的鍵。在各個線程內部,都使用這個公用的鍵來指代線程數據,但是在不同的線程中,這個鍵代表的數據是不同的。操作線程私有數據的函數主要有4個:pthread_key_create(創建一個鍵),pthread_setspecific(為一個鍵設置線程私有數據),pthread_getspecific(從一個鍵讀取線程私有數據),pthread_key_delete(刪除一個鍵)。這幾個函數的聲明如下:
    #include <pthread.h>
    int pthread_key_create(pthread_key_t *key,void (*destr_function)(void *));
    int pthread_setspecific(pthread_key_t key,const void *pointer));
    void *pthread_getspecific(pthread_key_t key);
    int pthread_key_delete(pthread_key_t key);
        pthread_key_create:從Linux的TSD池中分配一項,將其值賦給key供以后訪問使用,它的第一個參數key為指向鍵值的指針,第二個參數為一個函數指針,如果指針不為空,則在線程退出時將以key所關聯的數據為參數調用destr_function(),釋放分配的緩沖區。
        key一旦被創建,所有線程都可以訪問它,但各線程可以根據自己的需要往key中填入不同的值,這就相當于提供了一個同名而不同值的全局變量,一鍵多值。一鍵多值靠的是一個關鍵數據結構數組,即TSD池其結構如下:
    static struct pthread_key_struct pthread_keys[PTHREAD_KEYS_MAX] ={{0,NULL}};
        創建一個TSD就相當于將結構數組中的某一項設置為“in_use”,并將其索引返回給*key,然后設置destructor函數destr_function。
        pthread_setspecific:該函數將pointer的值(不是內容)與key相關聯。用pthread_setspecific為一個鍵指定新的線程數據時,線程必須先釋放原有的線程數據用以回收空間。
        pthread_getspecific:通過該函數得到與key相關聯的數據。
        pthread_key_delete:該函數用來刪除一個鍵,鍵所占用的內存將被釋放。需要注意的是,鍵占用的內存被釋放,與該鍵關聯的線程數據所占用的內存并不被釋放。因此,線程數據的釋放必須在釋放鍵之前完成。
        例8-4將實現如何創建和使用線程的私有數據,具體代碼如下所示。
        例8-4
    #include <stdio.h>
    #include <string.h>
    #include <pthread.h>

    pthread_key_t key;

    void * thread2(void *arg)
    {
    int tsd = 5;
    printf("thread %d is running\n",pthread_self());
    pthread_setspecific(key,(void *)tsd);
    printf("thread %d returns %d\n",pthread_self(),pthread_getspecific(key));
    }

    void * thread1(void *arg)
    {
    int tsd = 0;
    pthread_t thid2;

    printf("thread %d is running\n",pthread_self());
    pthread_setspecific(key,(void *)tsd);
    pthread_create(&thid2,NULL,thread2,NULL);
    sleep(2);
    printf("thread %d return %d\n",pthread_self(),pthread_getspecific(key));
    }

    int main(void)
    {
    pthread_t thid1;
    printf("main thread begins running\n");
    pthread_key_create(&key,NULL);
    pthread_create(&thid1,NULL,thread1,NULL);
    sleep(5);
    pthread_key_delete(key);
    printf("main thread exit\n");
    return 0;
    }
        編譯并執行,結果如下:
    $ gcc -o 8-4 8-4.c -g -l pthread
    $ ./8-4
    main thread begins running
    thread -1209746544 is running
    thread -1218139248 is running
    thread -1218139248 returns 5
    thread -1209746544 return 0
    main thread exit
        程序說明:程序中,主線程創建了線程thread1,線程thread1創建了線程thread2。兩個線程分別將tsd作為線程私有數據。從程序運行結果可以看出,兩個線程tsd的修改互不干擾,可以看出thread2先于thread1結束,線程在創建thread2后,睡眠3s等待thread2執行完畢。主線程睡眠5s等待thread1結束。可以看出thread2對tsd的修改并沒影響到thread1的tsd的取值。
    posted on 2010-05-29 15:16 何克勤 閱讀(2409) 評論(0)  編輯  收藏 所屬分類: GNU Linux/UnixLinux 多線程
    主站蜘蛛池模板: 九九九精品视频免费| 免费91最新地址永久入口| 免费欧洲毛片A级视频无风险| 三级片免费观看久久| 亚洲国产精品国自产拍AV| 中文字幕免费在线看线人| 在线观看亚洲专区| 亚洲av无码片区一区二区三区| 久久WWW免费人成人片| 成年免费大片黄在线观看com| 亚洲爆乳精品无码一区二区三区 | 国产午夜精品免费一区二区三区| 中文字幕亚洲综合久久| 日韩高清免费观看| 久久国产乱子精品免费女| 亚洲AV男人的天堂在线观看| 亚洲人成人无码网www电影首页| 美女被cao免费看在线看网站| 精品乱子伦一区二区三区高清免费播放| 久久亚洲春色中文字幕久久久| 日本特黄a级高清免费大片| 久久国产精品2020免费m3u8| 激情婷婷成人亚洲综合| 亚洲AV日韩精品久久久久久| 国产福利免费观看| 免费精品国偷自产在线在线| a在线免费观看视频| 美女视频黄频a免费| 亚洲国产成人综合| 青青草原亚洲视频| 国产大片91精品免费看3 | 国产亚洲精品资在线| 成年18网站免费视频网站| 香港a毛片免费观看| 一级毛片a免费播放王色电影| 亚洲中文字幕一二三四区苍井空| 亚洲国产香蕉碰碰人人| 久久狠狠躁免费观看| 羞羞视频免费网站日本| 亚洲精品国产高清在线观看| 亚洲精品午夜视频|