c++oding="utf-8" ?>
应调用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 <h3>为什么 std::this_thread::get_affinity() 现在不能用</h3>
<p>尽管 C++26 草案已定义 <code>std::this_thread::get_affinity()</code> 返回 <code>std::bitset</code>,但截至 2026 年 4 月,GCC 14.2 和 Clang 18 的标准库仍将其标记为 <code>TODO</code> 或直接未实现。调用它会链接失败或抛出 <code>std::system_error</code>(错误码 <code>ENOSYS</code>)。</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2823" title="C++14"><img
src="https://img.php.cn/upload/manual/001/431/639/6ac8b33c327c4749.png" alt="C++14" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="overflowclass">C++14</a>
<p class="overflowclass">C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。</p>
</div>
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<ul>
<li>头文件包含 <code><thread></thread></code> 不代表接口可用;需检查编译器文档中 “C++26 thread affinity support” 章节</li>
<li>即使编译通过,运行时返回的 <code>std::bitset</code> 大小可能是 0 或全 0,不代表真实掩码</li>
<li>若强行启用实验性 flag(如 <code>-fconcepts -std=c++26 -D_GLIBCXX_USE_CXX11_ABI=1</code>),仍可能因 libstdc++ 底层未桥接到 <code>sched_getaffinity</code> 而失效</li>
</ul>
<h3>如何验证打印结果是否真实有效</h3>
<p>光看程序输出不够,因为绑定可能已被父进程、容器或 systemd 限制覆盖。必须交叉验证系统视图。</p>
<ul>
<li>在程序启动后,立刻用 <code>ps -o pid,tid,%cpu,comm -T -p $(pidof your_program)</code> 查线程 ID(TID)</li>
<li>用 <code>taskset -p <tgt_tid></tgt_tid></code> 查该线程实际掩码(注意:不是 <code>taskset -p <pid></pid></code>,那是主线程)</li>
<li>或读 <code>/proc/<tgt_tid>/status</tgt_tid></code>,找 <code>Cpus_allowed_list:</code> 行,它比 <code>Cpus_allowed:</code> 更易读(显示 0-3,5 而非十六进制位图)</li>
<li>如果程序里打印的是 <code>0 2</code>,但 <code>taskset -p</code> 显示 <code>0x5</code>(即二进制 <code>101</code>),说明一致;若显示 <code>0xffffffff</code>,说明绑定根本没生效</li>
</ul>
<p>真正容易被忽略的是:亲和性掩码是 per-thread 的,且子线程默认继承父线程掩码 —— 如果你在主线程绑了 core 0,又用 <code>std::thread</code> 启动新线程却不重设,那新线程也会被锁在 core 0 上,可能造成严重争抢。动手前,先确认你查的是哪个线程、改的是哪个线程。</p></stdio.h></unistd.h></sched.h>
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










