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

为何sched_getaffinity返回包含已隔离CPU的亲和掩码?

问题分析:为什么isolcpus隔离的CPU仍出现在sched_getaffinity结果中

核心原因:isolcpus与CPU亲和性的区别

isolcpus内核参数的作用是让内核调度器默认不将普通进程调度到指定CPU上,但它并不会自动修改进程的CPU亲和掩码。进程的默认CPU亲和掩码会包含所有在线的CPU(包括被isolcpus隔离的CPU),这就导致sched_getaffinity会返回包含隔离CPU的结果——但实际上,调度器不会主动把进程调度到这些隔离CPU上,除非你手动通过sched_setaffinity或taskset工具将进程绑定到隔离CPU。

验证你的配置是否生效

你的系统配置是正确的:/proc/cmdline和/sys/devices/system/cpu/isolated都显示CPU 11,13,...33已被隔离。可以通过以下方式验证隔离是否生效:

  • 运行一个CPU密集型进程,用top或htop查看它的CPU占用,会发现它不会跑到隔离的CPU上;
  • 用taskset手动将进程绑定到隔离CPU(比如taskset -c 11 ./a.out),此时进程才会在隔离CPU上运行。

实现目标的解决方案

如果你的需求是获取进程实际可被调度到的CPU集合(排除isolcpus隔离的CPU),需要手动结合/sys/devices/system/cpu/isolated的内容对sched_getaffinity的结果进行过滤:

  1. 读取/sys/devices/system/cpu/isolated文件,解析出被隔离的CPU列表;
  2. 从sched_getaffinity返回的亲和掩码中移除这些CPU;
  3. 最终得到的就是进程实际可被调度到的CPU集合。

示例修改后的代码:

#include <iostream>
#include <sched.h>
#include <unistd.h>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>

std::vector<int> get_isolated_cpus() {
    std::vector<int> isolated;
    std::ifstream file("/sys/devices/system/cpu/isolated");
    if (!file.is_open()) {
        perror("open /sys/devices/system/cpu/isolated");
        return isolated;
    }
    std::string line;
    std::getline(file, line);
    std::stringstream ss(line);
    std::string token;
    while (std::getline(ss, token, ',')) {
        isolated.push_back(std::stoi(token));
    }
    return isolated;
}

int main() {
    cpu_set_t cpuset;
    CPU_ZERO(&cpuset);

    pid_t pid = getpid();
    if (sched_getaffinity(pid, sizeof(cpu_set_t), &cpuset) == -1) {
        perror("sched_getaffinity");
        return 1;
    }

    std::cout << "Process can run on CPUs (raw affinity mask): ";
    for (size_t i = 0; i < 32; ++i) {
        if (CPU_ISSET(i, &cpuset)) {
            std::cout << i << " ";
        }
    }
    std::cout << std::endl;

    std::vector<int> isolated_cpus = get_isolated_cpus();
    std::cout << "Process can be scheduled on CPUs (excluding isolated): ";
    for (size_t i = 0; i < 32; ++i) {
        if (CPU_ISSET(i, &cpuset)) {
            bool is_isolated = false;
            for (int cpu : isolated_cpus) {
                if (static_cast<size_t>(cpu) == i) {
                    is_isolated = true;
                    break;
                }
            }
            if (!is_isolated) {
                std::cout << i << " ";
            }
        }
    }
    std::cout << std::endl;

    return 0;
}

补充说明

  • CPU亲和掩码是进程的属性,决定了进程允许运行的CPU范围;
  • isolcpus是调度器的策略,决定了调度器是否会主动将进程放到某个CPU上;
  • 两者是独立的概念,isolcpus不会修改进程的亲和掩码,只是限制调度行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 18:47:23