博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在linux上获得线程id的方法,在linux上获得线程id的方法
阅读量:6470 次
发布时间:2019-06-23

本文共 1922 字,大约阅读时间需要 6 分钟。

在linux2.4版本后,linux使用了NPTL作为自己的线程库,为了兼容POSIX标准,所以在内核task中有两个域tgid和tid,前者是进程id,后者是线程id。在linux上获得线程id的方法,目前我所知的有三种,当然这里的三种是指在用户态的程序中,否则除非自己写的kernel module, 都是调用编号224的系统调用实现的(2.6版本)。第一种: gettid(), man gettid 可以看到gettid的使用方式。使用时要先定义:_syscall0(pid_t, gettid)其中_syscall0是一个宏(由于参数的不同还有_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}编译时,宏展开之后,相当于定义了一个pid_t gettid(void)函数,用内嵌汇编实现,在程序中就可以使用gettid()获得线程id了。第二种:syscall(), 名字叫syscall(),却是glibc中的库函数。使用方式:syscall(__NR_gettid), 其中__NR_gettid就是224,同上。syscall的实现要到glibc中去找,不同的硬件平台有不同的实现版本,在i386上的实现在syscall.S中:#include .textENTRY (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也是一个宏,展开了相当的长,主要用于在链接的时候让gcc能够"看见"并调用这段用汇编写成的syscall()函数。第三种:pthread_self()同样是一个glibc提供的函数,在linux的manual中说返回的是当前线程的thread ID.但是实际你看到的是一个很长的,似乎没有规律的值。什么原因得看看它的实现:在glibc中,pthread_self()返回的是THREAD_SELF,这又是一个宏定义如下# define THREAD_SELF \({ struct pthread *__self;      \asm ("movl %%gs:%c1,%0" : "=r" (__self)      \: "i" (offsetof (struct pthread, header.self)));      \__self;})这段代码返回了当前线程的descriptor,pthread_self()得到的就是这个descriptor的地址, 也就是unsigned long int类型的pthread_t。知道了这一点就好办了,找到thread descriptor的定义:struct pthread{...pid_t tid;...}接下来知道怎么做了吗?算好长度n,构造一个假的pthread结构。struct pthread_fake{void *nothing[n];pid_t tid;};用(struct pthread_fake *) pthread_self()->tid得到线程id了相比前两种做法,这种无疑是最繁琐的,但是同理,可以获取很多glibc中维护了,但是没有提供访问方法的数据。

posted on 2010-12-28 14:34 大龙 阅读(997) 评论(0)  编辑 收藏 引用

转载地址:http://dxdko.baihongyu.com/

你可能感兴趣的文章
可以免费下载视频素材和模板网站汇总
查看>>
node中非常重要的process对象,Child Process模块
查看>>
Webserver管理系列:3、Windows Update
查看>>
HDOJ 2151
查看>>
open-falcon
查看>>
doc2vec使用说明(一)gensim工具包TaggedLineDocument
查看>>
Q:图像太大,在opencv上显示不完全
查看>>
利用ItextPdf、core-renderer-R8 来生成PDF
查看>>
NavigationController的使用
查看>>
多线程编程之Windows环境下创建新线程
查看>>
Unity3D NGUI 给button按钮添加单间事件
查看>>
密码的校验.大小写字母,数字,特殊字符中的至少3种
查看>>
ios 不同sdk4.3 6.0版本号,关于方法的兼容性的通用方法
查看>>
js滚动加载到底部
查看>>
Virtualbox 虚拟机网络不通
查看>>
memcache数据库和redis数据库的区别(理论)
查看>>
我的友情链接
查看>>
MyBatis+Spring结合
查看>>
Office 365之SkyDrive Pro
查看>>
Java Web 高性能开发
查看>>