taskset 命令速查表 - CPU 亲和性绑核命令大全

taskset 解决的是「要不要让这个进程只用哪些核」,典型触发场景有三类:延迟毛刺但 CPU 利用率并不高(往往是跨 NUMA 节点访存或线程被调度到不同物理核上)、跑基准测试想减少迁移抖动、以及多租户机器上把自家进程隔离到空闲核避免被邻居抢占。它的实现只是改写任务的 CPU 亲和性掩码,所以从 jobs -l 或 /proc/<pid>/status 的 Cpus_allowed_list 可以随时核对是否真的绑住了。注意绑核并不必然变快:核数给少了并行度下降反而更慢,多线程进程只绑主线程更是白做,因此表里把 CPU 列表格式、十六进制掩码、绑定运行中进程、查看亲和性、NUMA 相关命令与 isolcpus 内核参数并列,方便对照选更合适的手段。

系统与运维·共 37 条命令·最后更新 2026-07-21
tasksetcpu性能调优

典型使用场景

面向做性能隔离、把「谁在抢我的核」变成可验证事实的工程师。taskset 是最轻的 CPU 隔离手段:不改内核、不建 cgroup、对运行中的 PID 立刻生效且随时可回退,适合在共享机器上给实时任务、数据库或某个 CPU 密集型进程圈定几个逻辑核。必须先建立的认知是它的边界:taskset 绑的是**逻辑 CPU 集合**,不是 NUMA 节点(那要 numactl),也不改变内核调度策略;而且在容器里它只能看到 cgroup 已经分配给你的 CPU,改了也绑不出去。

基础用法 6

taskset -p <pid>
查看进程 CPU 亲和性掩码
taskset -c -p <pid>
以 CPU 列表格式查看亲和性
taskset -c 0,1 <command>
启动时绑定到 CPU 0 和 1
taskset -c 0-3 <command>
启动时绑定到 CPU 0-3
taskset -p <mask> <pid>
修改运行中进程的 CPU 掩码
taskset -cp 0,1 <pid>
修改运行中进程绑定到 CPU 0,1

CPU 掩码与列表格式 7

0x00000001
十六进制掩码,CPU 0
0x00000003
十六进制掩码,CPU 0 和 1
0x0000000f
十六进制掩码,CPU 0-3
-c 0
CPU 列表格式,更易读
-c 0,2,4
指定多个离散 CPU
-c 0-3,8-11
混合范围列表
taskset -c 0xff <command>
使用十六进制掩码绑定 CPU 0-7

绑定运行中进程 4

taskset -cp 0 $(pgrep nginx)
修改 nginx 主进程的 CPU 亲和性
for p in $(pgrep -f app); do taskset -cp 0-3 $p; done
批量修改匹配进程的亲和性
taskset -cp 0-3 <pid>
将指定 PID 绑定到 CPU 0-3
taskset -ap 0-1 <pid>
设置进程及其所有线程的亲和性

查看亲和性与系统信息 5

cat /proc/<pid>/status | grep Cpus_allowed
查看进程 CPU 掩码
cat /sys/devices/system/cpu/online
查看系统在线 CPU 编号
nproc
查看可用 CPU 核心数
lscpu
查看 CPU 架构详情(核数、缓存、NUMA)
lscpu | grep NUMA
查看 NUMA 节点信息

NUMA 架构优化 5

numactl --hardware
查看 NUMA 拓扑和节点分布
numactl -c 0 -m 0 ./app
绑定 CPU 和内存到 NUMA 节点 0
numactl --cpunodebind=0 --membind=0 ./app
完整 NUMA 绑定(CPU+内存)
numastat -p <pid>
查看进程在各 NUMA 节点的内存分布
numactl --interleave=all ./app
内存交叉分配到所有节点

实用场景 5

taskset -c 0-3 ./cpu_intensive_app
限制应用使用特定核心
taskset -c 4-7 ./realtime_app
隔离核心给实时应用
taskset -c 0 nginx
绑定 Nginx worker 到特定核心
taskset -c 1,2 mysql
绑定 MySQL 到特定核心
isolcpus=2,3
内核参数:启动时隔离 CPU 2,3 不参与调度

相关工具 5

htop
交互式查看各 CPU 核心使用率
top -1
查看各 CPU 核心负载
mpstat -P ALL 1
实时监控各 CPU 核心(需 sysstat)
pidstat -t -p <pid> 1
查看进程各线程 CPU 使用
cset shield -c 4-7
cset 创建 CPU 隔离区(需安装 cset)

参数矩阵

参数作用示例
-c <list>以 CPU 列表格式指定亲和性,最易读,支持 0,1、0-3、0-3,8-11 混写taskset -c 0-3 <command>
-p <mask> <pid>查看或修改运行中进程的亲和性,不重启即可生效taskset -cp 0,1 <pid>
0x0000000f十六进制掩码写法,等价于 CPU 0-3;taskset 默认按掩码解析taskset -c 0xff <command>
-a作用于指定 PID 的所有线程而非仅主线程,多线程服务必须加taskset -ap 0-1 <pid>
Cpus_allowed_list/proc/<pid>/status 中的可观测字段,验证绑定是否真的生效cat /proc/<pid>/status | grep Cpus_allowed

易错点与避坑指南

现象taskset -cp 0,1 <pid> 报 Invalid argument,或者容器里绑定一个超出范围的 CPU 直接失败。

原因容器里能看到的是宿主 CPU 编号集合,但实际可用集合受 cgroup 限制;超出授权范围的任务会被内核拒绝。

处置先 cat /sys/devices/system/cpu/online 和 cat /proc/<pid>/status | grep Cpus_allowed 看真实可用集合再绑。

现象给多线程进程绑定后,htop 里仍有线程跑在别的核上。

原因不带 -a 时只作用于主线程(线程组 leader),其余线程各自为政。

处置改用 taskset -ap 0-1 <pid>,一次覆盖所有线程。

现象把进程绑到某些核后延迟反而变高,跨核访问内存频繁。

原因taskset 只绑 CPU,不绑内存位置;进程在 node 1 的核上跑却在读 node 0 的内存。

处置改用 numactl -c 0 -m 0 ./app 同时绑 CPU 与内存,或用 numactl --cpunodebind=0 --membind=0 ./app。

现象taskset -c 0-3 <command> 直接报错,提示亲和性里至少要有一个 CPU 在线。

原因指定范围里包含了离线 CPU,或本机在线编号并非从 0 连续排布。

处置用 nproc / cat /sys/devices/system/cpu/online 拿到真实在线编号后重新取值。

排障路径

  1. 1确认绑定是否真的生效

    cat /proc/<pid>/status | grep Cpus_allowed

    Cpus_allowed 是掩码、Cpus_allowed_list 是列表形式,两者必须与 taskset -p 的输出一致。

  2. 2批量给一个服务所有进程改亲和性

    for p in $(pgrep -f app); do taskset -cp 0-3 $p; done

    pgrep -f 按命令行匹配;漏掉 -a 时改的是主线程,需要 taskset -ap 0-3 $p。

  3. 3先摸清机器的 CPU 与 NUMA 拓扑

    nproc && lscpu | grep NUMA && numactl --hardware

    隔离前必须知道有哪些在线 CPU、有几个 NUMA 节点,否则掩码取了非法值。

  4. 4绑定后逐核观察是否真的分开了

    mpstat -P ALL 1

    需 sysstat;每核使用率分摊到预期的核上才算成功,pidstat -t -p <pid> 1 可看线程级分布。

命令示例

把 CPU 密集型应用限制在 CPU 0-3

taskset -c 0-3 ./cpu_intensive_app

这样应用永远不会调度到 0-3 之外的核,等于把它与其它负载物理隔开。

把 MySQL 固定在离散的两个核上

taskset -c 1,2 mysql

离散列表与 0-3 这类范围写法可以混用,混合时写成 0-3,8-11 即可。

批量把匹配到的进程都绑到 CPU 0-3

for p in $(pgrep -f app); do taskset -cp 0-3 $p; done

主进程派生出多个子进程时逐个改绑;脚本里 pgrep -f 匹配的是完整命令行,注意别把无关进程一起匹配进来。

核对某个进程真实生效的 CPU 掩码

cat /proc/12345/status | grep Cpus_allowed

输出里的 Cpus_allowed_list 是内核视角的权威结果,比你敲过的命令更能说明问题。

常见坑与注意事项

  • 改绑前先 taskset -p pid 记录原掩码,回滚时按原值改回,否则出问题无法还原到操作前的状态。
  • 多线程服务必须加 -a,只绑主线程会让其余线程继续在所有核之间游走,等于没做隔离。
  • 容器里 taskset 只能绑 cgroup 已经分配给你的 CPU,指定范围外的编号会直接报 Invalid argument。
  • 亲和性集合里至少要有一个在线 CPU,全部指定为离线 CPU 时 taskset 会拒绝执行。
  • 绑得太紧反而可能更慢,跨核访问内存的开销会抵消收益;NUMA 架构下需要 CPU 与内存同节点请改用 numactl。

提示

  • CPU 亲和性可以减少缓存失效,提升性能,但过度绑定可能导致负载不均。
  • 实时应用(如高频交易、音视频处理)适合绑定到隔离核心。
  • NUMA 架构下,CPU 和内存节点绑定能显著减少跨节点访问延迟。
  • taskset -c 使用 CPU 列表格式比十六进制掩码更易读,推荐日常使用。
  • isolcpus 内核参数在启动时隔离 CPU,比 taskset 更彻底但需重启生效。
  • 多线程进程需要用 -a 参数同时设置所有线程,否则只影响主线程。
  • taskset -pc 0-3 <PID> 改绑前先 taskset -pc <PID> 记录原 mask,回滚时按原值改回即可。
  • taskset -a 用于多线程进程,把所有线程一起绑;不加 -a 只改主线程,/proc/<PID>/task 下每个线程需单独处理。
  • lscpu -e=CPU,NODE 查看 CPU 与 NUMA 节点对应关系,绑核时让 CPU 号与目标内存节点就近可显著降延迟。

常见问题

taskset 绑的是 CPU 核还是 NUMA 节点?

绑的是逻辑 CPU 集合,一颗物理核在超线程下会算作两个逻辑 CPU,taskset 操作的粒度是后者。要按 NUMA 节点把 CPU 和内存一起绑到同一节点上,那不是 taskset 的活,要用 numactl --cpunodebind=0 --membind=0 这类命令,先用 numactl --hardware 看清节点分布。

taskset -c 0,1 command 和 taskset -cp 0,1 pid 有什么区别?

前者是启动时绑定:这个命令一启动就只能待在 CPU 0 和 1 上,进程退出后绑定随之消失。后者是改运行中的进程:传入已有 PID,把它的亲和性改成 CPU 0 和 1,不需要重启、立刻生效,进程照常运行。改之前建议先 taskset -p pid 记下原值以便回滚。

我给一个多线程服务绑了核,htop 里为什么还有线程跑在别的 CPU 上?

因为不加 -a 时只改了主线程的亲和性,其他线程各自保留原来的掩码。要把进程及其所有线程一起绑,写 taskset -ap 0-1 pid,-a 的作用就是把设置应用到该 PID 的每一个线程上。想确认每个线程的实际掩码,去 /proc/<pid>/status 里看 Cpus_allowed。

十六进制掩码 0x0000000f 到底对应哪几个 CPU?

从低位开始数,第 0 到第 3 位是 1,对应 CPU 0、1、2、3,也就是列表写法里的 0-3。同理 0x00000001 只是 CPU 0,0x00000003 是 CPU 0 和 1,0xff 则覆盖 CPU 0-7。因为掩码要自己数位,日常排查和配置更推荐 -c 列表格式。

改完亲和性怎么确认它真的生效了?

用 cat /proc/<pid>/status 配合 grep Cpus_allowed,输出里的 Cpus_allowed_list 就是当前实际允许的 CPU 集合,和你设置的列表一致才算生效。想做横向观察,htop 看每核使用率、mpstat -P ALL 1 看各核实时负载,绑定后各核负载是否真的分开了,是最直接的效果判据。

官方参考来源

下方为命令对应的官方权威文档,供你核对最新用法与深入查阅。

由 巧匠 维护

公开更新于 2026年7月21日,内容持续校对官方文档。

联系我们

命令或描述有误?提交反馈、商务合作或产品建议都可发送邮件给我们。

联系我们