Linux下sched_setaffinity()设置CPU亲和掩码后获取值未更新问题求助
我来帮你排查这个问题并解答你的疑问:
一、sched_setaffinity设置后不生效的原因及修复方法
你的代码核心问题是错误地将cpu_set_t类型当作普通的unsigned long来处理,cpu_set_t是Linux内核定义的位掩码结构体,并非单一的unsigned long变量,直接强转会导致内存操作错误,进而设置失败。具体错误点:
- 参数传递错误:
sched_getaffinity和sched_setaffinity的第二个参数需要传入cpu_set_t结构体的实际大小,而你传的是sizeof(pam)(指针大小,通常8字节)或sizeof(new_mask)(unsigned long大小,通常8字节),这在CPU数量较多的系统上会完全错误,即使CPU少的系统也会导致结构体未被正确读写。 - 类型强转错误:直接将
unsigned long*强转为cpu_set_t*,会破坏cpu_set_t的内部结构,导致内核无法正确解析掩码。
修复后的代码示例
#include <sched.h> #include <iostream> #include <unistd.h> #include <stdio.h> bool getprocess_affinitymask(pid_t pid, cpu_set_t* cpuset) { if (sched_getaffinity(pid, sizeof(cpu_set_t), cpuset) < 0) { perror("sched_getaffinity"); return false; } // 打印当前亲和掩码对应的CPU列表 printf("pid %d's get affinity: ", pid); for (int i = 0; i < CPU_SETSIZE; ++i) { if (CPU_ISSET(i, cpuset)) { printf("%d ", i); } } printf("\n"); return true; } bool setprocess_affinitymask(pid_t pid, const cpu_set_t* cpuset) { if (sched_setaffinity(pid, sizeof(cpu_set_t), cpuset) < 0) { perror("sched_setaffinity"); return false; } printf("pid %d's set affinity: ", pid); for (int i = 0; i < CPU_SETSIZE; ++i) { if (CPU_ISSET(i, cpuset)) { printf("%d ", i); } } printf("\n"); return true; } int main() { cpu_set_t cpuset; // 获取初始亲和掩码 getprocess_affinitymask(getpid(), &cpuset); // 设置新的亲和掩码:允许CPU 0、1、2、3(对应数值15,二进制1111) CPU_ZERO(&cpuset); CPU_SET(0, &cpuset); CPU_SET(1, &cpuset); CPU_SET(2, &cpuset); CPU_SET(3, &cpuset); setprocess_affinitymask(getpid(), &cpuset); // 再次验证设置结果 getprocess_affinitymask(getpid(), &cpuset); return 0; }
修复后输出示例
pid 1234's get affinity: 0 1 pid 1234's set affinity: 0 1 2 3 pid 1234's get affinity: 0 1 2 3
二、Linux中设置进程亲和掩码的权限要求
Linux没有Windows中PROCESS_SET_INFORMATION这样的单独权限,但有以下规则:
- 设置自身进程的亲和掩码:普通用户完全有权限操作,不需要任何特殊权限。
- 设置其他进程的亲和掩码:需要进程具备
CAP_SYS_NICE能力,你可以通过以下方式赋予:- 以root用户运行程序
- 使用
setcap命令给程序添加能力:sudo setcap cap_sys_nice+ep ./your_program
内容的提问来源于stack exchange,提问作者Anna
相关产品推荐
相关产品推荐

