You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决Linux系统cgroups v2 cpu控制器启用及实时线程问题

cgroups v2 CPU控制器启用与适配问题解答

1. 实时线程检测命令的局限性

你当前使用的ps -T axo pid,ppid,user,group,lwp,nlwp,start_time,comm,cgroup,cls|grep RR仅能捕获使用SCHED_RR调度策略的实时线程,无法覆盖所有实时线程。cgroups v2 CPU控制器限制的实时线程还包括使用SCHED_FIFO和SCHED_DEADLINE策略的线程,正确的检测命令应包含这三类:

ps -T axo pid,ppid,user,group,lwp,nlwp,start_time,comm,cgroup,cls | grep -E '(RR|FIFO|DEADLINE)'

其中cls列对应线程的调度类,上述三个值分别对应三种实时调度策略。

2. 实时线程重复生成的解决思路

直接杀死实时线程不可取(多为系统服务依赖的线程,会自动重启),正确做法是将这些线程移动到root cgroup,而非销毁:

  • 从上述检测命令中获取目标线程的LWP(轻量级进程ID)和当前cgroup路径;
  • 将LWP写入root cgroup的cgroup.procs文件,完成移动:
    echo <LWP> > /sys/fs/cgroup/cgroup.procs
    
  • 若线程属于systemd管理的服务,可通过修改服务配置文件(如/usr/lib/systemd/system/<service>.service)添加CPUAccounting=no或调整CGroup相关参数,避免服务启动时将线程放入非root cgroup。

3. Ubuntu 22.04 CPU控制器未启用的其他排查方向

即使清理了所有非root cgroup的实时线程,CPU控制器仍未出现,需排查以下几点:

  • 内核配置检查:确认内核是否开启了cgroups v2 CPU控制器支持,执行:
    zcat /proc/config.gz | grep CONFIG_CGROUP_CPU
    
    若输出为# CONFIG_CGROUP_CPU is not set,说明内核未编译该功能,需更换支持的内核或重新编译。
  • systemd配置限制:systemd可能未默认启用CPU控制器,检查/etc/systemd/system.conf中的DefaultControllers参数,确保包含cpu。修改后执行systemctl daemon-reexec重启systemd生效。
  • 内核日志排查:查看内核启动日志中cgroups相关报错:
    dmesg | grep cgroup
    
    若存在cpu controller cannot be enabled类提示,根据日志信息定位冲突项(如部分驱动或模块占用导致控制器无法加载)。

4. C/C++代码适配多发行版的CPU控制器使用方案

前置检测逻辑

代码中需先确认系统环境满足条件:

  1. 检测是否为cgroups v2环境:
    bool isCgroupV2() {
        struct statfs fs;
        if (statfs("/sys/fs/cgroup", &fs) == -1) return false;
        return fs.f_type == 0x63677270; // cgroup2fs的magic number
    }
    
  2. 检查root cgroup是否启用CPU控制器:
    bool hasCpuController() {
        FILE* fp = fopen("/sys/fs/cgroup/cgroup.controllers", "r");
        if (!fp) return false;
        char buf[256];
        bool found = false;
        while (fgets(buf, sizeof(buf), fp)) {
            if (strstr(buf, "cpu")) {
                found = true;
                break;
            }
        }
        fclose(fp);
        return found;
    }
    

CPU限制配置步骤(需root权限)

若环境满足条件,可创建自定义cgroup并设置CPU限制:

  1. 创建子cgroup目录:
    mkdir("/sys/fs/cgroup/myapp_cgroup", 0755);
    
  2. 启用CPU控制器(允许子cgroup使用):
    FILE* fp = fopen("/sys/fs/cgroup/myapp_cgroup/cgroup.subtree_control", "w");
    if (fp) {
        fprintf(fp, "+cpu");
        fclose(fp);
    }
    
  3. 设置CPU使用率上限(例如限制为50%,格式为max 100000,100000对应100%):
    fp = fopen("/sys/fs/cgroup/myapp_cgroup/cpu.max", "w");
    if (fp) {
        fprintf(fp, "50000 100000");
        fclose(fp);
    }
    
  4. 将当前进程加入该cgroup:
    pid_t pid = getpid();
    fp = fopen("/sys/fs/cgroup/myapp_cgroup/cgroup.procs", "w");
    if (fp) {
        fprintf(fp, "%d", pid);
        fclose(fp);
    }
    

发行版适配注意事项

  • RHEL9:默认已启用CPU控制器,可直接使用上述逻辑;
  • Ubuntu 22.04/CentOS9 Stream:需先通过内核配置、systemd调整启用CPU控制器,代码中需增加对控制器未启用场景的错误提示,引导用户先完成系统层面的配置。

内容的提问来源于stack exchange,提问作者JenyaKh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 00:07:49