Linux下用sched_getcpu()、Windows下用GetCurrentProcessorNumber()可轻量获取当前线程瞬时运行的核心编号,二者均返回逻辑CPU编号(从0开始),反映调度器当前分配的瞬时状态,而非绑定设置;跨平台时需避免误用affinity相关函数。

Linux下用sched_getcpu()直接获取核心编号
这是最轻量、最直接的方式,sched_getcpu() 是 glibc 提供的系统调用封装,返回当前线程正在运行的 CPU 核心逻辑编号(从 0 开始)。它不涉及上下文切换或调度器干预,开销极低。
注意:该函数仅在 Linux(glibc ≥ 2.6)上可用,Windows 和 macOS 均不支持。
- 必须包含头文件
<unistd.h>(不是<sys/syscall.h>) - 返回值为 int:成功时是核心编号(如 0、1、3),失败时为 -1(通常不会失败,除非内核严重异常)
- 它返回的是“当前时刻”所处的核心,不是绑定的核心——线程可能被调度器迁移,结果会变
#include <unistd.h>
#include <iostream>
int main() {
int cpu = sched_getcpu();
std::cout << "Running on CPU: " << cpu << std::endl;
return 0;
}
Windows下用GetCurrentProcessorNumber()替代
Windows 没有等价于 sched_getcpu() 的轻量接口,但 GetCurrentProcessorNumber() 功能相同:返回当前线程正在执行的逻辑处理器编号(从 0 开始),且同样无锁、低开销。
它自 Windows Vista / Server 2008 起可用,XP 不支持;需链接 kernel32.lib(通常默认链接)。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
立即学习“C++免费学习笔记(深入)”;
- 头文件:
<windows.h> - 返回值类型为
DWORD,非负整数,无需额外错误检查(失败时行为未定义,实际极少失败) - 和 Linux 版一样,反映的是瞬时状态,不能用于判断 affinity 设置是否生效
#include <windows.h>
#include <iostream>
int main() {
DWORD cpu = GetCurrentProcessorNumber();
std::cout << "Running on CPU: " << cpu << std::endl;
return 0;
}
跨平台封装时别误用 GetProcessAffinityMask
GetProcessAffinityMask()(Windows)和 sched_getaffinity()(Linux)返回的是进程/线程**允许运行的 CPU 掩码**,不是当前实际运行在哪。新手常混淆这两者,导致误以为“绑定了核心就一定在那跑”,其实调度器仍可临时迁移线程(除非用了 SCHED_FIFO + mlock 等严格策略)。
-
GetProcessAffinityMask()返回的是 bitset,需用_BitScanForward或 ffs() 解析最低位置位,不能直接当编号用 -
sched_getaffinity()返回的是cpu_set_t,要遍历CPU_ISSET()才能知道哪些核心被允许,更麻烦 - 若你真正想做的是“确认线程是否真的在目标核心上运行”,必须用
sched_getcpu()或GetCurrentProcessorNumber()实测,而非查掩码
多线程环境下结果可能秒变
即使你刚调用完 sched_getcpu() 得到结果是 2,下一条语句执行前,内核完全可能把线程迁移到核心 5——尤其在负载高、核心忙、或启用了节能调度(如 intel_pstate)时。
- 该值只适用于采样、日志、调试诊断,**不能用于控制逻辑分支**(比如“如果是核心 0 就做 A,否则做 B”)
- 若需稳定绑定,必须配合
sched_setaffinity()(Linux)或SetThreadAffinityMask()(Windows),且要注意绑定后可能降低整体吞吐(如 NUMA 访存延迟升高) - 在容器或虚拟机中,返回的编号是 guest OS 视角的逻辑 CPU 编号,未必对应物理核心,也受 vCPU 分配策略影响

















