• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            大龍的博客

            常用鏈接

            統(tǒng)計(jì)

            最新評(píng)論

            在linux上獲得線程id的方法

            在linux2.4版本后,linux使用了NPTL作為自己的線程庫(kù),為了兼容POSIX標(biāo)準(zhǔn),所以在內(nèi)核task中有兩個(gè)域tgid和tid,前者是進(jìn)程id,后者是線程id。在linux上獲得線程id的方法,目前我所知的有三種,當(dāng)然這里的三種是指在用戶態(tài)的程序中,否則除非自己寫的kernel module, 都是調(diào)用編號(hào)224的系統(tǒng)調(diào)用實(shí)現(xiàn)的(2.6版本)。 

            第一種: gettid(), man gettid 可以看到gettid的使用方式。 
            使用時(shí)要先定義:_syscall0(pid_t, gettid) 
            其中_syscall0是一個(gè)宏(由于參數(shù)的不同還有_syscall1,_syscall2...),定義如下: 
            #define _syscall0(type,name) \ 
            type name(void) \ 
            { \ 
            long __res; \ 
            __asm__ volatile ("int $0x80" \   //int 80, 軟中斷 
                    : "=a" (__res) \          //輸入輸出都用的eax 
                    : "0" (__NR_##name)); \   //#define __NR_gettid 224 
            __syscall_return(type,__res); \   //返回tid 
            } 
            編譯時(shí),宏展開(kāi)之后,相當(dāng)于定義了一個(gè)pid_t gettid(void)函數(shù),用內(nèi)嵌匯編實(shí)現(xiàn),在程序中就可以使用gettid()獲得線程id了。 

            第二種:syscall(), 名字叫syscall(),卻是glibc中的庫(kù)函數(shù)。 
            使用方式:syscall(__NR_gettid), 其中__NR_gettid就是224,同上。 
            syscall的實(shí)現(xiàn)要到glibc中去找,不同的硬件平臺(tái)有不同的實(shí)現(xiàn)版本,在i386上的實(shí)現(xiàn)在syscall.S中: 
            #include <sysdep.h> 
            .text 
            ENTRY (syscall) 
            PUSHARGS_6 /* Save register contents.  */ 
            _DOARGS_6(44) /* Load arguments.  */ 
            movl 20(%esp), %eax /* Load syscall number into %eax.  */ 
            ENTER_KERNEL /* Do the system call.  */ 
            POPARGS_6 /* Restore register contents.  */ 
            cmpl $-4095, %eax /* Check %eax for error.  */ 
            jae SYSCALL_ERROR_LABEL /* Jump to error handler if error.  */ 
            L(pseudo_end): 
            ret /* Return to caller.  */ 
            PSEUDO_END (syscall) 
            其中ENTRY也是一個(gè)宏,展開(kāi)了相當(dāng)?shù)拈L(zhǎng),主要用于在鏈接的時(shí)候讓gcc能夠"看見(jiàn)"并調(diào)用這段用匯編寫成的syscall()函數(shù)。 

            第三種:pthread_self() 
            同樣是一個(gè)glibc提供的函數(shù),在linux的manual中說(shuō)返回的是當(dāng)前線程的thread ID.但是實(shí)際你看到的是一個(gè)很長(zhǎng)的,似乎沒(méi)有規(guī)律的值。什么原因得看看它的實(shí)現(xiàn): 
            在glibc中,pthread_self()返回的是THREAD_SELF,這又是一個(gè)宏 
            定義如下 
            # define THREAD_SELF \ 
              ({ struct pthread *__self;      \ 
                  asm ("movl %%gs:%c1,%0" : "=r" (__self)      \ 
             : "i" (offsetof (struct pthread, header.self)));      \ 
                  __self;}) 
            這段代碼返回了當(dāng)前線程的descriptor,pthread_self()得到的就是這個(gè)descriptor的地址, 也就是unsigned long int類型的pthread_t。知道了這一點(diǎn)就好辦了,找到thread descriptor的定義: 
            struct pthread 
            { 
            ... 
                     pid_t tid; 
            ... 
            } 

            接下來(lái)知道怎么做了嗎?算好長(zhǎng)度n,構(gòu)造一個(gè)假的pthread結(jié)構(gòu)。 
            struct pthread_fake 
            { 
            void *nothing[n]; 
            pid_t tid; 
            }; 
            用(struct pthread_fake *) pthread_self()->tid得到線程id了 
            相比前兩種做法,這種無(wú)疑是最繁瑣的,但是同理,可以獲取很多glibc中維護(hù)了,但是沒(méi)有提供訪問(wèn)方法的數(shù)據(jù)。

            posted on 2010-12-28 14:34 大龍 閱讀(1207) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            久久精品国产亚洲AV影院 | 久久99九九国产免费看小说| 无码人妻久久一区二区三区免费 | 久久精品国产亚洲沈樵| 久久久久久综合网天天| 性做久久久久久久久| 久久久久这里只有精品 | 欧美噜噜久久久XXX| 天堂久久天堂AV色综合| 狠狠色丁香久久婷婷综合| 国产一区二区久久久| 久久天天躁狠狠躁夜夜躁2014| 精品伊人久久大线蕉色首页| 亚洲AV乱码久久精品蜜桃| 久久大香香蕉国产| 久久精品视频免费| 久久精品中文字幕第23页| 无码任你躁久久久久久| 蜜桃麻豆WWW久久囤产精品| 欧洲精品久久久av无码电影| 久久综合久久综合九色| 久久男人中文字幕资源站| 欧美午夜A∨大片久久| 伊人久久久AV老熟妇色| 久久综合九色综合网站| 伊人久久大香线焦综合四虎| 天天综合久久一二三区| 久久精品aⅴ无码中文字字幕重口| 99久久成人国产精品免费| 狠狠久久综合伊人不卡| 久久亚洲精品无码aⅴ大香| 亚洲色婷婷综合久久| 99久久99久久精品国产片果冻| 亚洲精品99久久久久中文字幕 | 久久久久久夜精品精品免费啦| 99久久精品九九亚洲精品| 少妇熟女久久综合网色欲| 一本伊大人香蕉久久网手机| 伊人久久无码中文字幕| 久久久久亚洲AV无码专区网站 | 国产精品99久久精品|