3. taskset 命令入门:查看与设置 CPU 亲和性
在 DPDK 多核任务绑定场景中,taskset 是最基础、最直接的 CPU 亲和性配置工具。它允许用户查看当前进程的 CPU 亲和性掩码,并将进程绑定到指定的 CPU 核心上运行。本章将系统讲解 taskset 的语法、常用操作及典型应用场景。
核心概念: CPU 亲和性(CPU Affinity)决定了一个进程或线程可以在哪些 CPU 核心上运行。通过
taskset 设置亲和性,可以避免进程在核心间频繁迁移,从而减少缓存失效和上下文切换开销。
3.1 taskset 基本语法
taskset 命令的语法格式如下:
taskset [options] mask command [argument...]
taskset [options] -p [mask] pid
参数说明:
| 参数 | 说明 | 示例 |
|---|---|---|
mask |
CPU 亲和性掩码,可用十六进制或 CPU 列表格式 | 0x01 或 0-3 |
-p |
操作已运行的进程(需指定 PID) | taskset -p 0x0f 1234 |
-c |
使用 CPU 列表格式(如 0,2,4) |
taskset -c 0,2 ./app |
command |
要启动并绑定的命令 | taskset 0x01 ./dpdk-worker |
pid |
目标进程 ID | taskset -p 0x03 5678 |
提示: 掩码的每一位对应一个 CPU 核心(从 0 开始编号)。例如
0x03(二进制 0011)表示绑定到 CPU 0 和 CPU 1;0x0f(二进制 1111)表示绑定到 CPU 0~3。
3.2 查看进程亲和性
使用 taskset -p pid 可以查看指定进程当前的 CPU 亲和性掩码:
# 查看 PID 为 1234 的进程亲和性
$ taskset -p 1234
pid 1234's current affinity mask: 3
输出中的 3 是十六进制掩码,表示该进程可以运行在 CPU 0 和 CPU 1 上。如果需要更直观的 CPU 列表显示,可以加上 -c 选项:
$ taskset -cp 1234
pid 1234's current affinity list: 0,1
查看系统中所有 CPU 核心的编号:
$ lscpu | grep "CPU(s)"
CPU(s): 8
On-line CPU(s) list: 0-7
注意: 在 NUMA 架构系统中,CPU 核心编号可能不是连续的。建议先使用
lscpu 或 numactl --hardware 确认核心拓扑,再进行绑定操作。
3.3 设置进程亲和性
场景一:启动新进程并绑定到指定核心
# 将 dpdk-worker 绑定到 CPU 0 和 CPU 2
$ taskset -c 0,2 ./dpdk-worker
# 使用十六进制掩码:CPU 0 (bit0) + CPU 2 (bit2) = 0x05
$ taskset 0x05 ./dpdk-worker
场景二:修改已运行进程的亲和性
# 将 PID 5678 绑定到 CPU 0~3
$ taskset -p 0x0f 5678
# 使用 CPU 列表格式
$ taskset -cp 0-3 5678
场景三:绑定到单个核心(DPDK 常用)
# 将进程绑定到 CPU 3 上独占运行
$ taskset -c 3 ./dpdk-lcore-worker
3.4 绑定到指定 CPU 核心:典型流程
下图展示了使用 taskset 将 DPDK 工作进程绑定到指定核心的完整流程:
3.5 常用操作速查表
| 操作场景 | 命令示例 | 说明 |
|---|---|---|
| 查看进程亲和性 | taskset -p 1234 |
显示十六进制掩码 |
| 查看进程亲和性(列表) | taskset -cp 1234 |
显示 CPU 编号列表 |
| 启动并绑定到单核 | taskset -c 3 ./app |
绑定到 CPU 3 |
| 启动并绑定到多核 | taskset -c 0,2,4 ./app |
绑定到 CPU 0、2、4 |
| 修改运行中进程 | taskset -p 0x0f 5678 |
将 PID 5678 绑定到 CPU 0~3 |
| 绑定到连续核心范围 | taskset -c 0-3 ./app |
绑定到 CPU 0 到 3 |
| 查看所有核心信息 | lscpu | grep -E "CPU|Core|Socket" |
确认核心拓扑 |
3.6 常见问题与避坑指南
- 权限不足: 修改其他用户的进程亲和性需要 root 权限,使用
sudo或切换为 root 用户。 - 核心编号错误: 在 NUMA 系统中,核心编号可能不是从 0 开始连续排列,务必先使用
lscpu确认。 - 掩码格式混淆:
taskset -c 0,2和taskset 0x05效果相同,但-c更直观,推荐在脚本中使用。 - 绑定后无法迁移: 一旦绑定,除非显式修改,否则进程不会自动迁移到其他核心。
- 子进程继承: 使用
taskset启动的进程,其子进程默认继承父进程的亲和性设置。
DPDK 最佳实践: 在 DPDK 应用中,通常将每个 lcore 绑定到独立的物理核心,避免超线程核心。例如在 8 核系统上,使用
taskset -c 0,2,4,6 ./dpdk-app 绑定到物理核心,跳过超线程核心 1,3,5,7。