Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

1. 应用场景

在软件开发和系统设计,有时需要控制控制指定进程的CPU资源使用率,如以下这些场景:

  1. 保障关键服务/高优先级应用的性能。
  2. 防止某些失控进程拖垮系统。
  3. 资源成本优化与预算控制。
  4. 温度控制与功耗管理。
  5. 云服务器中,多租户环境资源隔离与公平性。

2. 实现方式

在Linux系统中,如何控制指定进程的CPU资源使用率主要通过以下几种核心方法实现。

2.1. nicerenice (调整优先级)

  • 原理: 通过修改进程的优先级 (nice值),影响内核调度器分配 CPU 时间片的频率。nice值范围通常为 -20 (最高优先级,抢 CPU 最积极) 到 19 (最低优先级,最谦让)。
  • 控制方式:
    • 启动时设置: nice -n <nice值> <命令> (例如: nice -n 10 ./cpu_intensive_job)
    • 运行时调整: renice -n <新nice值> -p <PID> (例如: renice -n 15 -p 1234)
  • 特点: 相对简单,影响进程获取 CPU 的机会权重,非严格上限。高 nice值 进程在系统繁忙时获得的 CPU 时间显著减少,空闲时仍可使用空闲 CPU。

2.2. cpulimit (临时性软限制)

  • 原理: 通过周期性地向目标进程发送 SIGSTOPSIGCONT 信号,强制其暂停和恢复运行,从而将进程的 CPU 使用率限制在设定的百分比内。
  • 控制方式:
    • 启动时限制: cpulimit -l <百分比> <命令> (例如: cpulimit -l 50 ./myapp)
    • 运行时限制: cpulimit -l <百分比> -p <PID> (例如: cpulimit -l 30 -p 5678)
  • 特点:
    • 易于使用,限制直观(百分比)。
    • 是软限制,进程在暂停期间不消耗 CPU,但恢复后会尽力运行直到再次被暂停。
    • 开销相对较大(需要监控进程并频繁发信号)。
    • 重启后失效,适合临时性、交互式的限制。

2.3. cgroups (控制组 - 最强大和推荐的方法)

2.3.1. 原理

Linux 内核提供的资源隔离和限制机制。通过将进程分组 (cgroup),并为该组设置各种资源(CPU、内存、I/O 等)的限制参数。

2.3.2. 核心子系统

1. cpu 子系统:

使用 CFS (Completely Fair Scheduler) 带宽控制器。主要参数:

  • cpu.cfs_period_us: 统计周期长度(微秒,默认 100ms = 100000us)。
  • cpu.cfs_quota_us: 在 period 内,该组中所有进程总共可使用的 CPU 时间(微秒)。配额 / 周期 ≈ 最大 CPU 使用率 (例如 quota=50000, period=100000 -> 50% 限制)。

2. cpuset 子系统

将进程绑定到特定的 CPU 核心上运行(限制可用核心范围)。

2.3.3. 控制方式

1. 使用 systemd (推荐):

  1. 创建 scope 或 service: sudo systemd-run --scope --slice=<自定义slice名> <命令> (临时) 或 创建自定义的 .service 文件 (持久)。
  2. 编辑 slice 或 service 的配置 (e.g., /etc/systemd/system/<slice名>.slice/etc/systemd/system/<service名>.service):
1
2
3
[Slice]
CPUQuota=50% # 限制该 slice 下所有进程总共使用 50% 的单个 CPU 核心
AllowedCPUs=0-1 # (可选) 只允许使用 CPU 0 和 1
  1. 重载配置并启动/重启服务: sudo systemctl daemon-reload + sudo systemctl restart <service名>

2. 直接操作 cgroup 文件系统 (通常挂载在 /sys/fs/cgroup):

  • 创建 cgroup: sudo mkdir /sys/fs/cgroup/cpu/<组名>
  • 设置限制: echo 50000 | sudo tee /sys/fs/cgroup/cpu/<组名>/cpu.cfs_quota_us (限制 50%)
  • 将进程 PID 加入 cgroup: echo <PID> | sudo tee /sys/fs/cgroup/cpu/<组名>/cgroup.procs

2.3.4. 特点

  • 强大精确: 可设置硬性上限、权重、核心绑定。
  • 层次化: 支持嵌套组,资源配额可继承和共享。
  • 持久化: 结合 systemd 可轻松实现开机自动限制。
  • 容器基础: Docker/Kubernetes 等容器技术依赖 cgroups 进行资源隔离。
  • 现代标准: 是 Linux 上管理进程资源(尤其是后台服务)的首选方法。

2.4. taskset (CPU 亲和性 - 限制可用核心)

  • 原理: 将进程或线程绑定 (pinning) 到特定的 CPU 核心上运行。
  • 控制方式:
    • 启动时绑定: taskset -c <核心列表> <命令> (例如: taskset -c 0,1 ./app 绑定到核心 0 和 1)
    • 运行时绑定: taskset -pc <核心列表> <PID> (例如: taskset -pc 2,3 9876)
  • 特点:
    • 不直接限制 CPU 使用率百分比,但通过限制进程可用的核心数,间接限制了其最大 CPU 占用(最多只能跑满绑定的核心)。
    • 主要目的是优化缓存利用、减少上下文切换开销,但在核心数少于绑定的进程数时也能起到限制作用。
    • 通常与 cgroupsnice 结合使用。

3. 监控工具 (验证限制效果)

  • top / htop: 查看进程的 %CPU, NI (nice值), 运行在哪个核心 (PCPU 列)。
  • pidstat (sysstat 包): 更详细的进程级统计,如 %usr, %system, %guest, CPU (核心号)。pidstat -p <PID> 1 每秒刷新一次。
  • cpustat / atop: 更高级的系统性能监控工具。
  • 查看 cgroup 统计: 在 cgroup 目录下 (如 /sys/fs/cgroup/cpu/<组名>) 查看 cpu.stat, cpuacct.usage 等文件。

4. 关键考虑因素

  1. 权限: nice/renice/taskset 普通用户可降低自身进程优先级,**提高优先级或限制他人进程需要 root**。cpulimit/cgroups 配置通常需要 root
  2. 严格性 vs 灵活性:
    • cgroups (CFS quota) 提供硬性上限
    • cpulimit软性、尽力而为的上限,有开销。
    • nice/renice优先级调整,无绝对上限。
    • taskset资源范围隔离
  3. 持久性:
    • cgroups + systemd 可实现开机自动生效的限制。
    • nice/renice/cpulimit/taskset 的效果通常在进程重启后失效
  4. 范围:
    • cgroups 天然支持对一组进程进行统一限制。
    • 其他工具主要针对单个进程 (虽然 renice/taskset 也可作用于进程组)。
  5. 实时进程 (SCHED_FIFO/SCHED_RR): 这些高优先级实时进程通常不受 nice 和 CFS 配额限制的影响。限制它们需要专门的实时调度策略配置或避免使用实时优先级。
推荐阅读
Linux系统监控数据 - /proc/stat Linux系统监控数据 - /proc/stat Linux常用命令 - 查看端口被哪个进程占用 Linux常用命令 - 查看端口被哪个进程占用 windows11 wsl 里的VSCode 出现如下报错:The window terminated unexpectedly(reason crashed, code -36861) windows11 wsl 里的VSCode 出现如下报错:The window terminated unexpectedly(reason crashed, code -36861)

评论