乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Posix線(xiàn)程編程指南(2)

       omcc 2011-01-10

      2001 年 10 月 01 日

      這是一個(gè)關(guān)于Posix線(xiàn)程編程的專(zhuān)欄。作者在闡明概念的基礎(chǔ)上,將向您詳細(xì)講述Posix線(xiàn)程庫(kù)API。本文是第二篇將向您講述線(xiàn)程的私有數(shù)據(jù)。

      概念及作用

      在單線(xiàn)程程序中,我們經(jīng)常要用到"全局變量"以實(shí)現(xiàn)多個(gè)函數(shù)間共享數(shù)據(jù)。在多線(xiàn)程環(huán)境下,由于數(shù)據(jù)空間是共享的,因此全局變量也為所有線(xiàn)程所共有。但有時(shí)應(yīng)用程序設(shè)計(jì)中有必要提供線(xiàn)程私有的全局變量,僅在某個(gè)線(xiàn)程中有效,但卻可以跨多個(gè)函數(shù)訪(fǎng)問(wèn),比如程序可能需要每個(gè)線(xiàn)程維護(hù)一個(gè)鏈表,而使用相同的函數(shù)操作,最簡(jiǎn)單的辦法就是使用同名而不同變量地址的線(xiàn)程相關(guān)數(shù)據(jù)結(jié)構(gòu)。這樣的數(shù)據(jù)結(jié)構(gòu)可以由Posix線(xiàn)程庫(kù)維護(hù),稱(chēng)為線(xiàn)程私有數(shù)據(jù)(Thread-specific Data,或TSD)。





      回頁(yè)首


      創(chuàng)建和注銷(xiāo)

      Posix定義了兩個(gè)API分別用來(lái)創(chuàng)建和注銷(xiāo)TSD:

      int pthread_key_create(pthread_key_t *key, void (*destr_function) (void *))

      該函數(shù)從TSD池中分配一項(xiàng),將其值賦給key供以后訪(fǎng)問(wèn)使用。如果destr_function不為空,在線(xiàn)程退出(pthread_exit())時(shí)將以key所關(guān)聯(lián)的數(shù)據(jù)為參數(shù)調(diào)用destr_function(),以釋放分配的緩沖區(qū)。

      不論哪個(gè)線(xiàn)程調(diào)用pthread_key_create(),所創(chuàng)建的key都是所有線(xiàn)程可訪(fǎng)問(wèn)的,但各個(gè)線(xiàn)程可根據(jù)自己的需要往key中填入不同的值,這就相當(dāng)于提供了一個(gè)同名而不同值的全局變量。在LinuxThreads的實(shí)現(xiàn)中,TSD池用一個(gè)結(jié)構(gòu)數(shù)組表示:

      static struct pthread_key_struct pthread_keys[PTHREAD_KEYS_MAX] = { { 0, NULL } };

      創(chuàng)建一個(gè)TSD就相當(dāng)于將結(jié)構(gòu)數(shù)組中的某一項(xiàng)設(shè)置為"in_use",并將其索引返回給*key,然后設(shè)置destructor函數(shù)為destr_function。

      注銷(xiāo)一個(gè)TSD采用如下API:

      int pthread_key_delete(pthread_key_t key)

      這個(gè)函數(shù)并不檢查當(dāng)前是否有線(xiàn)程正使用該TSD,也不會(huì)調(diào)用清理函數(shù)(destr_function),而只是將TSD釋放以供下一次調(diào)用pthread_key_create()使用。在LinuxThreads中,它還會(huì)將與之相關(guān)的線(xiàn)程數(shù)據(jù)項(xiàng)設(shè)為NULL(見(jiàn)"訪(fǎng)問(wèn)")。





      回頁(yè)首


      訪(fǎng)問(wèn)

      TSD的讀寫(xiě)都通過(guò)專(zhuān)門(mén)的Posix Thread函數(shù)進(jìn)行,其API定義如下:

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

      寫(xiě)入(pthread_setspecific())時(shí),將pointer的值(不是所指的內(nèi)容)與key相關(guān)聯(lián),而相應(yīng)的讀出函數(shù)則將與key相關(guān)聯(lián)的數(shù)據(jù)讀出來(lái)。數(shù)據(jù)類(lèi)型都設(shè)為void *,因此可以指向任何類(lèi)型的數(shù)據(jù)。

      在LinuxThreads中,使用了一個(gè)位于線(xiàn)程描述結(jié)構(gòu)(_pthread_descr_struct)中的二維void *指針數(shù)組來(lái)存放與key關(guān)聯(lián)的數(shù)據(jù),數(shù)組大小由以下幾個(gè)宏來(lái)說(shuō)明:

      #define PTHREAD_KEY_2NDLEVEL_SIZE       32
                  #define PTHREAD_KEY_1STLEVEL_SIZE               ((PTHREAD_KEYS_MAX + PTHREAD_KEY_2NDLEVEL_SIZE - 1)
                  / PTHREAD_KEY_2NDLEVEL_SIZE)
                  其中在/usr/include/bits/local_lim.h中定義了PTHREAD_KEYS_MAX為1024,因此一維數(shù)組大小為32。而具體存放的位置由key值經(jīng)過(guò)以下計(jì)算得到:
                  idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE
                  idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE

      也就是說(shuō),數(shù)據(jù)存放與一個(gè)32×32的稀疏矩陣中。同樣,訪(fǎng)問(wèn)的時(shí)候也由key值經(jīng)過(guò)類(lèi)似計(jì)算得到數(shù)據(jù)所在位置索引,再取出其中內(nèi)容返回。





      回頁(yè)首


      使用范例

      以下這個(gè)例子沒(méi)有什么實(shí)際意義,只是說(shuō)明如何使用,以及能夠使用這一機(jī)制達(dá)到存儲(chǔ)線(xiàn)程私有數(shù)據(jù)的目的。

      #include <stdio.h>
                  #include <pthread.h>
                  pthread_key_t   key;
                  void echomsg(int t)
                  {
                  printf("destructor excuted in thread %d,param=%d\n",pthread_self(),t);
                  }
                  void * child1(void *arg)
                  {
                  int tid=pthread_self();
                  printf("thread %d enter\n",tid);
                  pthread_setspecific(key,(void *)tid);
                  sleep(2);
                  printf("thread %d returns %d\n",tid,pthread_getspecific(key));
                  sleep(5);
                  }
                  void * child2(void *arg)
                  {
                  int tid=pthread_self();
                  printf("thread %d enter\n",tid);
                  pthread_setspecific(key,(void *)tid);
                  sleep(1);
                  printf("thread %d returns %d\n",tid,pthread_getspecific(key));
                  sleep(5);
                  }
                  int main(void)
                  {
                  int tid1,tid2;
                  printf("hello\n");
                  pthread_key_create(&key,echomsg);
                  pthread_create(&tid1,NULL,child1,NULL);
                  pthread_create(&tid2,NULL,child2,NULL);
                  sleep(10);
                  pthread_key_delete(key);
                  printf("main thread exit\n");
                  return 0;
                  }

      給例程創(chuàng)建兩個(gè)線(xiàn)程分別設(shè)置同一個(gè)線(xiàn)程私有數(shù)據(jù)為自己的線(xiàn)程ID,為了檢驗(yàn)其私有性,程序錯(cuò)開(kāi)了兩個(gè)線(xiàn)程私有數(shù)據(jù)的寫(xiě)入和讀出的時(shí)間,從程序運(yùn)行結(jié)果可以看出,兩個(gè)線(xiàn)程對(duì)TSD的修改互不干擾。同時(shí),當(dāng)線(xiàn)程退出時(shí),清理函數(shù)會(huì)自動(dòng)執(zhí)行,參數(shù)為tid。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀(guān)點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶(hù) 評(píng)論公約

        類(lèi)似文章 更多