直接用 taskset -p <pid> 就能看到进程允许运行的 CPU 掩码,但这个值不是它“此刻在哪跑”——要看实时落点得查 psr 列。
怎么一眼看出进程能跑在哪些 CPU 上
执行 taskset -p <pid>,输出类似 pid 1234's current affinity mask: 0x3f。这个十六进制数要转成二进制看:0x3f = 00111111,从右往左,bit 0 对应 CPU 0,bit 1 对应 CPU 1……所以它允许在 CPU 0–5 上运行。
更省事的做法是加 -c 参数:taskset -cp <pid>,直接输出 pid 1234's current affinity list: 0-3,6,8-10,连范围和步长(如 8-10:2)都帮你解析好了。
- 普通用户只能查自己启动的进程;查
systemd或内核线程需 root 权限 - 掩码位数上限为 64 位,但超出物理核心数的高位会被忽略(比如 32 核机器上设
0xffffffffffffffff等效于全开) - 输出中若出现
0-6:2,表示 CPU 0、2、4、6 —— 合法但不常用
怎么确认进程“现在正跑在哪个 CPU”
taskset 显示的是“允许在哪跑”,不是“正在哪跑”。一个进程即使绑定了 CPU 0–3,调度器仍可能让它短暂落在 CPU 2 上执行——只要没被抢占或迁移,就符合亲和性规则。
真正反映当前落点的是 ps -o pid,psr,comm -p <pid> 中的 psr 列,它显示的是 last used CPU 编号(从 0 开始)。
- 多线程程序必须对每个线程 TID 单独查,因为线程才是调度单位;漏掉就可能误判
- 如果
psr长期固定在某个非绑定范围内 CPU,说明绑定失败,或子线程在代码里调了pthread_setaffinity_np()覆盖了父进程设置 - 虚拟机中
psr显示的是 vCPU 编号,不是宿主机物理核编号
修改后怎么验证亲和性真生效了
改完别只信 taskset -p 输出。得持续观察 psr 是否稳定在你设定的范围内:
watch -n1 'ps -o pid,psr,comm -p <pid>' 看几秒,确认值不再跳变。
- 若仍跳变,先检查是否用了
-a参数——多线程进程需显式加-a才对所有线程设亲和性 - 再查是否有更高优先级的调度策略(如
SCHED_FIFO)覆盖了亲和性限制 - 注意:启动时绑定用
taskset -c 1,3 ./app;修改已有进程必须带-p,否则命令会误以为你要启动一个叫 “1234” 的新程序
最容易被忽略的一点:psr 是瞬时快照,单次查看意义不大;必须持续观察几秒以上,才能判断调度是否真的收敛到目标 CPU。很多问题其实不是绑定没生效,而是没等够时间看效果。
原创文章,作者:phoenix,如若转载,请注明出处:http://blog.if98.com/it/528.shtml
微信扫一扫
支付宝扫一扫 