应调用sched_getaffinity(0, sizeof(cpuset), &cpuset)获取当前线程亲和性掩码,先CPU_ZERO清空位图,再用CPU_ISSET遍历sysconf(_SC_NPROCESSORS_ONLN)获知的逻辑CPU数打印允许的核心编号。

直接用 sched_getaffinity 获取掩码,再遍历 cpu_set_t 位图打印;别依赖 std::this_thread::get_affinity() —— 它在绝大多数生产环境(GCC 13/Clang 17、libstdc++/libc++ 当前稳定版)尚未实现。
怎么用 sched_getaffinity 打印当前线程允许运行的核心列表
Linux 下最可靠、零依赖的方式就是调用 sched_getaffinity。它不依赖 pthread 扩展,也不要求 glibc 特定版本,只要内核支持(2.5.8+)就稳。
-
sched_getaffinity(0, sizeof(cpuset), &cpuset)中的0表示“当前线程”,不是进程 ID,这点极易写错 - 必须先用
CPU_ZERO(&cpuset)清空位图,否则未初始化的内存可能触发EINVAL - 遍历时用
CPU_ISSET(cpu, &cpuset)判断第cpu位是否置 1(cpu从 0 开始) - 最大核心数不能硬写
64或128,应调用sysconf(_SC_NPROCESSORS_ONLN)动态获取
#include <sched.h>
#include <unistd.h>
#include <stdio.h>
void print_current_affinity() {
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
int ret = sched_getaffinity(0, sizeof(cpuset), &cpuset);
if (ret != 0) {
perror("sched_getaffinity failed");
return;
}
int ncpus = sysconf(_SC_NPROCESSORS_ONLN);
printf("Allowed CPUs: ");
for (int i = 0; i < ncpus; i++) {
if (CPU_ISSET(i, &cpuset)) {
printf("%d ", i);
}
}
printf("\n");
}
为什么 std::this_thread::get_affinity() 现在不能用
尽管 C++26 草案已定义 std::this_thread::get_affinity() 返回 std::bitset,但截至 2026 年 4 月,GCC 14.2 和 Clang 18 的标准库仍将其标记为 TODO 或直接未实现。调用它会链接失败或抛出 std::system_error(错误码 ENOSYS)。
- 头文件包含
<thread></thread>不代表接口可用;需检查编译器文档中 “C++26 thread affinity support” 章节 - 即使编译通过,运行时返回的
std::bitset大小可能是 0 或全 0,不代表真实掩码 - 若强行启用实验性 flag(如
-fconcepts -std=c++26 -D_GLIBCXX_USE_CXX11_ABI=1),仍可能因 libstdc++ 底层未桥接到sched_getaffinity而失效
如何验证打印结果是否真实有效
光看程序输出不够,因为绑定可能已被父进程、容器或 systemd 限制覆盖。必须交叉验证系统视图。
立即学习“C++免费学习笔记(深入)”;
- 在程序启动后,立刻用
ps -o pid,tid,%cpu,comm -T -p $(pidof your_program)查线程 ID(TID) - 用
taskset -p <tgt_tid></tgt_tid>查该线程实际掩码(注意:不是taskset -p <pid></pid>,那是主线程) - 或读
/proc/<tgt_tid>/status</tgt_tid>,找Cpus_allowed_list:行,它比Cpus_allowed:更易读(显示 0-3,5 而非十六进制位图) - 如果程序里打印的是
0 2,但taskset -p显示0x5(即二进制101),说明一致;若显示0xffffffff,说明绑定根本没生效
真正容易被忽略的是:亲和性掩码是 per-thread 的,且子线程默认继承父线程掩码 —— 如果你在主线程绑了 core 0,又用 std::thread 启动新线程却不重设,那新线程也会被锁在 core 0 上,可能造成严重争抢。动手前,先确认你查的是哪个线程、改的是哪个线程。



















