c++oding="utf-8" ?>
最直接查看所有线程调度信息的方法是ps -t -o pid,tid,pri,nice,comm -p :pri显示动态优先级(0–139),其中0–99为实时线程,100–139为cfs普通线程;nice仅对普通线程有效(-20~+19)。

用ps -T -o pid,tid,pri,nice,comm 查当前进程所有线程的调度信息
这是最直接、无需代码改动、能快速看到全部线程优先级状态的方法。Linux内核通过 ps 的线程视图暴露了每个线程的静态优先级(pri)和 nice 值(nice),二者共同影响实际调度权重。
关键点在于:pri 列显示的是内核计算出的“动态优先级”(范围 0–139),其中 0–99 是实时线程(SCHED_FIFO/RR),100–139 是 CFS 管理的普通线程;而 nice 只对普通线程有效(-20 到 +19),它会平移 CFS 的虚拟运行时间,从而间接改变调度顺序。
执行命令示例:
ps -T -o pid,tid,pri,nice,comm -p <your_pid></your_pid>
常见陷阱:
-
pri值恒为 120 左右?大概率所有线程都走 SCHED_OTHER,没设实时策略 - 看到
pri= 99 或更低?说明有线程用了 SCHED_FIFO/SCHED_RR,需立刻确认是否必要——这类线程一旦忙等或阻塞在低效 I/O 上,极易饿死其他线程 -
nice为负但pri没变?说明该线程是实时策略,nice被忽略
用pthread_getschedparam在代码中读取指定线程的调度策略和优先级
当你需要在运行时精确获取某个线程(尤其是自己创建的 std::thread)的当前调度参数时,必须调用 POSIX API pthread_getschedparam。它返回两个关键值:调度策略(policy)和结构体 sched_param 中的 sched_priority。
注意:sched_priority 在 SCHED_OTHER 下恒为 0,不代表“低”,只是 CFS 不使用该字段;只有 SCHED_FIFO/SCHED_RR 下这个值才真实生效(通常 1–99)。
实操要点:
- 对
std::thread,先调th.native_handle()得到pthread_t,再传给pthread_getschedparam - 必须检查返回值是否为 0,非零表示失败(如线程已分离、权限不足、或句柄无效)
- 不要在主线程里查子线程——除非你确保子线程已启动且未退出;更稳妥的做法是在子线程函数开头就查并记录
为什么top -H看不到准确的线程优先级?
top -H 默认显示的 PR 列其实是内核的“动态优先级”,它混合了调度策略、nice 值、CPU 使用历史等多种因素,不是你设置的那个 sched_priority。它适合观察负载趋势,但不适合验证你是否成功设置了 SCHED_FIFO 优先级为 50。
真正反映你主动配置的字段,是 ps 的 pri 和 nice,或者用 chrt -p <tid></tid> 查策略与实时优先级:
chrt -p <tid></tid>
输出类似 sched policy: SCHED_FIFO, sched priority: 50 才算落到了实处。
容易被忽略的细节:
-
chrt对普通用户只能查自己的线程;查别人进程需 root 权限 - 即使
chrt -p显示策略是 SCHED_OTHER,也不能排除该线程被内核临时提升(如因 futex 等同步原语触发的优先级继承) - 一个线程的调度策略可能在生命周期中被多次修改,仅看某一次快照不够可靠
std::thread::native_handle() 返回值类型不跨平台,别硬 cast
很多开发者试图把 std::thread::native_handle() 强转成 pthread_t* 或 HANDLE,这是危险操作。libstdc++ 返回的是 pthread_t 值,而 libc++ 返回的是指向内部结构的指针——二者二进制布局完全不同。
正确做法只有一种:用 #ifdef __linux__ 或 #ifdef _WIN32 显式分发,且只在对应平台下调用 pthread_getschedparam 或 GetThreadPriority。
例如,在 Linux 分支里这样写才安全:
#ifdef __linux__
pthread_t pt = static_cast<pthread_t>(th.native_handle());
int policy;
struct sched_param param;
if (pthread_getschedparam(pt, &policy, ¶m) == 0) {
// 成功读取
}
#endif</pthread_t>
跨平台封装时,宁可让非 Linux 平台返回 “not supported”,也不要尝试统一类型转换——崩溃比静默错误更难排查。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











