pthread_self() VS syscall(SYS_gettid)
在多线程中,pthread_self()函数获得的线程号是pthread库对线程的编号,而不是Linux系统对线程的编号。
pthread_create()返回的线程号,使用top命令是查不到的,top显示的是Linux的线程号。
在单线程中,Linux 的线程号和进程号是一样的。
在多线程中,主线程的线程号(main函数的线程)与进程号一样,其他线程则有各自的线程号。
与getpid()函数不同的是,Linux并没有直接给一个gettid()的API,而是使用syscall()直接用SYS_gettid的系统调用号去获取线程号。
系统调用,是用户程序使用系统内核功能的API。
一般会把常用的系统调用封装为C函数,例如常用的open、close、read、write等函数。
实际上,每个系统调用是有编号的,在内核里构成一个系统调用表,就是个很大的函数指针数组,调用号就是对应功能的数组索引。
用户把调用号和参数传给内核,就可以使用系统功能了。
熟悉汇编的,肯定还记得MS-DOS著名的int 21H中断:(
Linux则是int 0x80。
x64有syscall指令,软件中断不再使用int指令了。
Linux也提供了一个函数syscall(),如下图,不再需要自己写汇编码了。
如果想“21天学写操作系统”,那么还是要自己写的:(
第一个参数,就是需要的系统调用号,以SYS_开头的宏,不需要记具体的号码。
随后的都是该系统调用的参数列表,可能无参数,也可以不止一个,是可变的。
获取Linux的线程号是SYS_gettid,该调用没有参数,与getpid()类似。
见下图代码。
最后这两张图可以看出:
在top -H -p 时显示的tid,
与syscall(SYS_gettid)返回的一致,
与pthread_self返回的不一致,后者的与pthread_create获得的一致。