不同平台获取当前线程 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相关推荐

  1. python多线程的使用(导入线程模块、创建子线程任务、启动子线程任务、获取当前执行的线程号)

    1. 导入线程模块 #导入线程模块 import threading 2. 线程类Thread参数说明 Thread([group [, target [, name [, args [, kwarg ...

  2. Java的知识点30——线程的优先级、终止线程的典型方式、获取线程基本信息的方法

    线程的优先级  1-10 1. NORM_PRIORITY  5 默认  2. MIN_PRIORITY  1  3. MAX_PRIORITY  10 注意:优先级低只是意味着获得调度的概率低.并不 ...

  3. java 线程转储_获取Java线程转储的常用方法(推荐)

    1. 线程转储简介 线程转储(Thread Dump)就是JVM中所有线程状态信息的一次快照. 线程转储一般使用文本格式, 可以将其保存到文本文件中, 然后人工查看和分析, 或者使用工具/API自动分 ...

  4. Java 线程实例二(终止线程、生产者/消费者问题、获取线程状态、获取所有线程、查看线程优先级、中断线程)

    终止线程 Java中原来在Thread中提供了stop()方法来终止线程,但这个方法是不安全的,所以一般不建议使用. 本文向大家介绍使用interrupt方法中断线程. 使用interrupt方法来终 ...

  5. 线程名称的获取与修改

    修改线程的名称 方式一 线程对象的setName方法 方式二 实例化线程的时候传参 获取当前线程对象 Thread.currentThread() 获取线程名称 在类的内部 this.getName( ...

  6. 线程池异步线程中再次获取线程池资源的问题

    问题描述 在线上发生的一次问题, 在场景中有这样一个业务, 需要异步执行一个主任务, 主任务中又包含着N个子任务, 为了整个主任务能够快速处理, 又将子任务按照数量获取线程资源异步处理, 即异步线程A ...

  7. java 获取所有线程,Java 实例 - 获取所有线程

    以下实例演示了如何使用 getName() 方法获取所有正在运行的线程: /* author by shouce.ren Main.java */ public class Main extends ...

  8. 《Java程序员面试秘笈》—— 1.3 线程信息的获取和设置

    本节书摘来异步社区<Java 7并发编程实战手册>一书中的第1章,第1.3节,作者:[西]Javier Fernández González,更多章节内容可以访问云栖社区"异步社 ...

  9. Java线程栈的获取和分析

    获取进程号 使用命令:jps 常用参数: -m 输出传递给main方法的参数,如果是内嵌的JVM则输出为null. -l 输出应用程序主类的完整包名,或者是应用程序JAR文件的完整路径. -v 输出传 ...

最新文章

  1. (转)Android SharedPreferences的使用
  2. 【NOIP校内模拟】塔
  3. 知乎高赞:看懂这个颠覆世界观的认知,远比做1000道题更有用!
  4. CF Edu54 E. Vasya and a Tree DFS+树状数组
  5. 字符串型的数字相加减_【每日编程158期】罗马数字转整数
  6. vim自定义语法高亮(syntax highlight)设置流程
  7. Activiti的BPMN2.0中的子流程
  8. (day 17 - 快排)剑指 Offer 40. 最小的k个数
  9. UIFont 字体设置
  10. Android网络验证逆向,【Android逆向】去除无聊的网络验证弹窗与360加固
  11. UG NX 12.0入门
  12. 通过IP地址和子网掩码,如何计算出网络地址、广播地址和主机数?
  13. 类模板 Class Templates
  14. 谢尔宾斯基三角形:Python+turtle
  15. 微信小程序广告接入,小程序加广告
  16. 如何修改电脑的MAC地址(手把手更改)
  17. windows操作系统知识最全
  18. ubuntu conda环境安装包安装
  19. Support Vector Machine学习笔记
  20. 杰理之 MIC录音 vbat电压低于3.2v会有很强的底噪?【篇】

热门文章

  1. 10、如何查看MySQL系统帮助?
  2. 设CPU中各部件及其相互连接关系如下图所示。图中W是写控制标志,R是读控制标志,R 1 和R 2 是暂存器
  3. Spring boot的Hello World入门
  4. MySQL为表和字段取别名
  5. fortran语言和python_如何在Fortran中调用Python
  6. 【JUC并发编程03】线程间通信
  7. 【盘它!】那些让效率MAX的工具和方法(Mac篇)
  8. 信息系统项目管理知识--项目成本管理
  9. Android使用WebView加载网页
  10. 【Spring注解系列12】@Value与@PropertySource注解