线程标识(线程ID)

一、线程标识

  • 和进程的Pid一样,每个线程也有对应的id即tid
  • 在线程中,线程ID的类型是pthread_t类型,由于在Linux下线程采用POSIX标准,所以,在不同的系统下,pthread_t的类型是不同的,比如在ubuntn下,是unsigned long类型,而在solaris系统中,是unsigned int类型。而在FreeBSD上才用的是结构体指针。 所以不能直接使用==判读,而应该使用pthread_equal来判断

二、获取线程ID的方法

  • gettid或者类似gettid的方法(使用系统调用)
  • 直接调用pthread_self()函数
获取线程ID的方法说明
1、使用gettid方法
  • gettid并没有直接在glibc中实现,因此无法在程序中直接使用这个函数,与之类似的方法是执行系统调用。
  • a、首先查询该系统调用的调用号(在文件arch/arm64/Include/Asm/Unistd32.h中)(以linux-3.18.x举例)
#define __NR_fcntl64 221
__SYSCALL(__NR_fcntl64, compat_sys_fcntl64)
			/* 222 for tux */
__SYSCALL(222, sys_ni_syscall)
			/* 223 is unused */
__SYSCALL(223, sys_ni_syscall)
#define __NR_gettid 224
__SYSCALL(__NR_gettid, sys_gettid)
#define __NR_readahead 225
__SYSCALL(__NR_readahead, compat_sys_readahead_wrapper)
#define __NR_setxattr 226
__SYSCALL(__NR_setxattr, sys_setxattr)
  • b、使用系统调用来获取内核线程ID
#include <sys/syscall.h>  
printf("The ID of this thread is: %ld\n", (long int)syscall(224));
2、直接调用pthread_self()函数获取id
#include <stdio.h>
#include <pthread.h>
printf("pthread_self: %ld\n", pthread_self());

三、知识点补充

  • 线程的标识有两个【内核中的线程ID】【posix描述的线程ID(也就是用户层glibc库中的线程ID)】
  • gettid 获取的是内核中真实线程ID, 对于多线程进程来说,每个tid实际是不一样的。而pthread_self获取的是相对于进程的线程控制块的首地址, 只是用来描述同一进程中的不同线程,
  • gettid及使用系统调用方法获取到的id是内核中的线程id,pthread_self()获取到的是posix描述的ID
  • 对于单线程的进程,内核中的tid==pid。对于多线程的进程,他们拥有相同的pid和不同的tid。
  • pthread_self()返回的id和内核中线程的id是不一样的,当一个线程退出后,新创建的线程可以复用原来的id

四、分为两个线程id的原因

  • 因为线程库实际上由两部分组成:内核的线程支持+用户态的库支持(glibc),linux上的线程实现就是在内核支持的基础上以POSIX thread的方式对外封装了接口,所以才会有两个ID的问题。

参考整理文献:https://blog.csdn.net/rsyp2008/article/details/45150621

猜你喜欢

转载自blog.csdn.net/weixin_38239856/article/details/83183961