用 taskset -p 查看进程允许运行的 cpu 核心(掩码格式),用 ps -o pid,psr,comm -p 中的 psr 列确认其当前实际运行的核心;taskset -cp 可直接显示可读的 cpu 列表(如 0-1 或 0,2,5-7)。

直接看进程当前允许运行在哪几个 CPU 核心上,用 taskset -p <pid></pid>;想确认它此刻实际跑在哪个核,得看 ps -o pid,psr,comm -p <pid></pid> 里的 psr 列。
查看进程 CPU 亲和性掩码和可读列表
执行 taskset -p <pid></pid> 输出的是十六进制掩码,比如 pid 1234's current affinity mask: 0x3,对应二进制 0011,表示允许在 CPU 0 和 CPU 1 上运行。最低位是 CPU 0,以此类推。
更直观的方式是加 -c 参数:taskset -cp <pid></pid>,会直接显示类似 pid 1234's current affinity list: 0-1 或 0,2,5-7 这样的范围写法,省去手动换算。
- 普通用户只能查自己启动的进程;查系统进程(如
systemd)需 root 权限 - 输出中若出现步长(如
0-6:2),表示 CPU 0、2、4、6 —— 这是合法语法,但不常用 - 掩码位数上限为 64 位,但超出物理核心数的高位会被忽略(例如 64 核机器上设
0xffffffffffffffff等效于全开)
验证进程“此刻”真正在哪个 CPU 上运行
taskset 显示的是“允许运行在哪”,不是“正在运行在哪”。一个进程即使绑定了 CPU 0–3,调度器仍可能让它短暂落在 CPU 2 上执行——只要没被抢占或迁移,就符合亲和性规则。
要观察实时落点,用:ps -o pid,psr,comm -p <pid></pid>,其中 psr 列就是 last used CPU 的编号(从 0 开始)。多线程程序需对每个线程 TID 单独查,因为线程才是调度单位。
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
- 如果
psr值长期固定在某个非绑定范围内 CPU,说明绑定失败或被覆盖(比如子线程在代码里调了pthread_setaffinity_np()) -
top -H -p <pid></pid>+ 按f→ 选中P(Last CPU used)列,适合持续观察多个线程的分布 - 虚拟机中
psr显示的是 vCPU 编号,不是宿主机物理核编号
启动时绑定 vs 运行中修改:参数组合别搞混
启动新进程绑定很简单:taskset -c 1,3 ./app;但修改已有进程必须带 -p,否则命令会误以为你要启动一个叫 “1234” 的新程序。
常见错误写法:taskset -c 0,2 1234(缺 -p)→ 实际执行的是 “以 CPU 0,2 绑定方式运行名为 1234 的命令”,而非修改 PID 1234。
- 正确写法是:
taskset -p -c 0,2 1234或等价的taskset -pc 0,2 1234 - 多线程程序建议加
-a(--all-tasks):比如taskset -apc 0,1 1234,否则只改主线程 TID,子线程仍按默认策略调度 - 用掩码格式时注意:
taskset 0x5 1234是错的(缺-p),应写成taskset -p 0x5 1234
为什么绑定了还是看到进程在其他 CPU 上跑?
绑定生效 ≠ 进程永远卡死在某核。Linux 调度器仍可在你指定的亲和集内自由切换——比如绑了 CPU 0 和 2,它可能在 0 上跑 10ms,再切到 2 上跑 5ms,这完全合法且常见。
真正“只在一个核上不动”的情况极少,通常只出现在以下场景:
- 进程处于
S(sleep)或R(running)状态且无中断/抢占,刚好被调度到某核并长时间占用 - 配合
isolcpus=内核启动参数隔离出专用 CPU,并禁用该核上的 timer 中断 - 用
cgroup v2 cpuset配合cpuset.cpus+cpuset.mems强约束(比taskset更硬)
单纯靠 taskset 无法阻止内核在绑定集内做负载均衡或迁移,这是它的设计边界——它管的是“允许范围”,不是“强制落点”。










