c++ 获取线程id_高效获取当前线程的 id
不同平台获取当前线程 id 的方法
- Windows
可以利用微软提供的 api,轻松获取当前线程的 id:
int id = GetCurrentThreadId();
- Linux
Linux 平台一般用的是 pthread 线程库,但它并不提供获取线程内部 id 的方法。可以通过系统调用得到当前线程的 id:
#include <unistd.h> // for syscall()
#include <sys/syscall.h> // for SYS_xxx definitionsint id = syscall(SYS_gettid);
- Mac
Mac 平台也可以用 syscall
获取当前线程的 id,与 Linux 稍有区别:
#include <unistd.h> // for syscall()
#include <sys/syscall.h> // for SYS_xxx definitionsint id = syscall(SYS_thread_selfid); // for mac os x
不过在 mac os x 10.12 之后,syscall 被标记为 deprecated,所以最好还是用下面的方法取代 syscall:
#include <pthread.h>uint64_t id;
pthread_threadid_np(0, &id); // non-posix, supported by BSD
基于 TLS 的优化
系统调用会在用户态与内核态之间来回切换,相对比较耗时。为了避免频繁的系统调用,可以用 TLS 优化,每个线程只需一次系统调用:
inline int tls_get_tid() {static __thread int id = 0;if (id != 0) return id;id = syscall(SYS_gettid);return id;
}
下面是一段简单的测试代码:
inline int sys_get_tid() {return syscall(SYS_gettid);
}void fsys() {int v = 0;Timer t;for (int i = 0; i < 1000000; i++) {v = sys_get_tid();}int64 us = t.us();cout << "fsys use " << us << "us" << " id: " << v << endl;
}void ftls() {int v = 0;Timer t;for (int i = 0; i < 1000000; i++) {v = tls_get_tid();}int64 us = t.us();cout << "ftls use " << us << "us" << " id: " << v << endl;
}
在 Linux 系统编译执行结果如下:
# ./xx
fsys use 299251us id: 71
ftls use 2675us id: 71
可以看到 TLS
版本性能提升了将近 100 倍,效果非常明显。
在 windows 上也进行了类似的测试,结果表明 TLS 对性能没什么影响,可能 windows 的 api 内部就是用 TLS 机制实现的。
c++ 获取线程id_高效获取当前线程的 id相关推荐
- python多线程的使用(导入线程模块、创建子线程任务、启动子线程任务、获取当前执行的线程号)
1. 导入线程模块 #导入线程模块 import threading 2. 线程类Thread参数说明 Thread([group [, target [, name [, args [, kwarg ...
- Java的知识点30——线程的优先级、终止线程的典型方式、获取线程基本信息的方法
线程的优先级 1-10 1. NORM_PRIORITY 5 默认 2. MIN_PRIORITY 1 3. MAX_PRIORITY 10 注意:优先级低只是意味着获得调度的概率低.并不 ...
- java 线程转储_获取Java线程转储的常用方法(推荐)
1. 线程转储简介 线程转储(Thread Dump)就是JVM中所有线程状态信息的一次快照. 线程转储一般使用文本格式, 可以将其保存到文本文件中, 然后人工查看和分析, 或者使用工具/API自动分 ...
- Java 线程实例二(终止线程、生产者/消费者问题、获取线程状态、获取所有线程、查看线程优先级、中断线程)
终止线程 Java中原来在Thread中提供了stop()方法来终止线程,但这个方法是不安全的,所以一般不建议使用. 本文向大家介绍使用interrupt方法中断线程. 使用interrupt方法来终 ...
- 线程名称的获取与修改
修改线程的名称 方式一 线程对象的setName方法 方式二 实例化线程的时候传参 获取当前线程对象 Thread.currentThread() 获取线程名称 在类的内部 this.getName( ...
- 线程池异步线程中再次获取线程池资源的问题
问题描述 在线上发生的一次问题, 在场景中有这样一个业务, 需要异步执行一个主任务, 主任务中又包含着N个子任务, 为了整个主任务能够快速处理, 又将子任务按照数量获取线程资源异步处理, 即异步线程A ...
- java 获取所有线程,Java 实例 - 获取所有线程
以下实例演示了如何使用 getName() 方法获取所有正在运行的线程: /* author by shouce.ren Main.java */ public class Main extends ...
- 《Java程序员面试秘笈》—— 1.3 线程信息的获取和设置
本节书摘来异步社区<Java 7并发编程实战手册>一书中的第1章,第1.3节,作者:[西]Javier Fernández González,更多章节内容可以访问云栖社区"异步社 ...
- Java线程栈的获取和分析
获取进程号 使用命令:jps 常用参数: -m 输出传递给main方法的参数,如果是内嵌的JVM则输出为null. -l 输出应用程序主类的完整包名,或者是应用程序JAR文件的完整路径. -v 输出传 ...
最新文章
- (转)Android SharedPreferences的使用
- 【NOIP校内模拟】塔
- 知乎高赞:看懂这个颠覆世界观的认知,远比做1000道题更有用!
- CF Edu54 E. Vasya and a Tree DFS+树状数组
- 字符串型的数字相加减_【每日编程158期】罗马数字转整数
- vim自定义语法高亮(syntax highlight)设置流程
- Activiti的BPMN2.0中的子流程
- (day 17 - 快排)剑指 Offer 40. 最小的k个数
- UIFont 字体设置
- Android网络验证逆向,【Android逆向】去除无聊的网络验证弹窗与360加固
- UG NX 12.0入门
- 通过IP地址和子网掩码,如何计算出网络地址、广播地址和主机数?
- 类模板 Class Templates
- 谢尔宾斯基三角形:Python+turtle
- 微信小程序广告接入,小程序加广告
- 如何修改电脑的MAC地址(手把手更改)
- windows操作系统知识最全
- ubuntu conda环境安装包安装
- Support Vector Machine学习笔记
- 杰理之 MIC录音 vbat电压低于3.2v会有很强的底噪?【篇】
热门文章
- 10、如何查看MySQL系统帮助?
- 设CPU中各部件及其相互连接关系如下图所示。图中W是写控制标志,R是读控制标志,R 1 和R 2 是暂存器
- Spring boot的Hello World入门
- MySQL为表和字段取别名
- fortran语言和python_如何在Fortran中调用Python
- 【JUC并发编程03】线程间通信
- 【盘它!】那些让效率MAX的工具和方法(Mac篇)
- 信息系统项目管理知识--项目成本管理
- Android使用WebView加载网页
- 【Spring注解系列12】@Value与@PropertySource注解