你了解linxu下的线程id吗?

背景

最近在实现一个日志库时,需要记录线程id,我采用C++ 11中的std::thread api获取,如下例子代码:

#include <thread>
#include <iostream>

int main()
{
    std::thread::id tid = std::this_thread::get_id();
    std::cout << tid << std::endl;
    std::getchar();
}

输出

3676

上面是在windows上vs2015获取的tid值,看着是一个整型,很正常。

如果在linux g++ 环境下编译,输出如下:

139627072304960

一长串奇怪的数字,看到这个结果,我很诧异,在我的印象中,它应该跟windows下输出一样,是个正常的数字(没这么长)。为什么会有这样的印象:

我在linux调试程序时,通过top -Hp pid命令看到的进程中线程的id(在我的理解中)是这样的:

top -Hp 18156

PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
18156 mjh       20   0   22996   1112    936 S  0.0  0.0   0:00.00 threadid
18157 mjh       20   0   22996   1112    936 S  0.0  0.0   0:00.00 threadid

如上top -Hp 命令,查看pid为18156的进程中线程资源占用情况,第一列PID理解成线程ID。这个值不像上面的程序那样返回一长串数字。
所以我认为g++ 下的std::thread::id的实现与我所理解的线程ID不一样。所以我写下面的一个测试代码(通过pthread_self获取thread id)

#include <iostream>
#include <thread>

int main()
{
   std::cout<<std::this_thread::get_id()<<std::endl;
   std::cout<<pthread_self()<<std::endl;
   std::getchar();

}

在通过std::thread获取thread id的同时,也通过pthread_self()获取thread id,结果如下:

140586156734272
140586156734272

值一样,说明std::thread::get_id()获取的就是thread id。那么可以肯定,是我对thread id的理解有误了,那top -Hp 看到线程pid是什么?它跟thread id有什么不一样?

结论

通过一顿猛如虎的搜索,终于搞清楚了这些id的意义:

pthread_xxx系列API是POSIX中的标准,linux对pthread库的实现是通过内核级的轻量级进程来实现的。这些进程就跟普通的进程一样,有自己的pid可以被单独调度

那么就很显然了,top -Hp中的pid其实是内核中对应用户态的线程的进程的pid

线程id是有线程库所分配的,它是独立于进程空间的,就是不同的进程间,线程id可能会一样。线程id只在进程空间内有效。

g++中std::thread的实现也是基于pthread,产生线程ID只在进程空间内有效,通过 syscall(__NR_gettid) 获取线程的PID。

那么我们在实现诸如log这样的工具库时,应该记录线程的PID,通过这个PID可以直接配合一些进程资源监控工具(比如:top)来使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mo4776

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值