获取线程标识函数gettid和pthread_self的区别

来源:互联网 发布:淘宝卖家如何做好运营 编辑:程序博客网 时间:2024/06/05 14:33
最近阅读源码时发现了有两种获取线程ID的函数:pthread_self和gettid,前者在Richard的APUE一书中有详尽介绍,但后者函数相对陌生,经过一番查阅后现将这两者在此总结一番。

pthread_self:
pthread_self是POSIX实现的,它返回一个由pthread_t数据类型表示的线程ID,在Linux系统中用无符号整形来表示pthread_t数据类型。
POSIX线程ID的分配和维护是由线程实现决定的,它表示的是同一进程中各个线程的独立标识,所以由pthread_self返回的线程ID仅在其所属的进程上下文中才有意义。另外,由于pthread_t应该被当做不透明的数据(opaque data)类型实现,所以当要比较两个pthread_t时可以调用pthread_equal函数来完成操作。

gettid:
gettid是由Linux 2.4版本引入的一个新的系统调用,该函数允许一个线程拥有其系统内独立的线程ID。
同getpid()一样,调用gettid()后也会返回一个pid_t类型,由该类型表示的线程ID由内核保证在系统范围内唯一,除非该线程是其所属进程的主线程(Linux线程实现中,线程实际也是一个进程,主线程的线程ID和其所在的进程ID一样)。

对比:
由pthread_self得到的POSIX线程ID和由Linux中系统调用getpid返回的线程ID不是同一事物,前者是由线程实现来分配和维护的,仅在其所属进程中具有唯一值,同时该接口具有可移植性;后者类似于进程ID,是由内核来分配维护的,在整个系统范围内具有唯一值,但其不具备可移植性(仅能工作于Linux中)。

gettid的使用:

在glibc中并未提供gettid接口的声明,使用者需要自行使用syscall来调用该此函数。

#include <sys/syscall.h>

printf("main loop thread id: %ld\n", syscall(SYS_gettid));

也可以创建包裹函数来方便调用:

#include <sys/syscall.h>

pid_t gettid() { return syscall(SYS_gettid); }


当然,也可以根据/usr/include/asm/unistd.h文件中可以找到如下定义(不同编译环境可能有所差异):

#define __NR_gettid     186
__SYSCALL(_NR_gettid,  sys_gettid)

所以也可以按照如下方式调用(当然为了移植性不建议这么做)

printf("main loop thread id: %ld\n", syscall(186));

printf("main loop thread id: %ld\n", syscall(__NR_gettid));


原创粉丝点击