GetSystemInfo().dwNumberOfProcessors 返回系统可见的逻辑核心数,即OS调度器可用的线程总数,不受进程级CPU亲和性影响,Windows下最轻量可靠。

Windows下用GetSystemInfo获取逻辑核心数
Windows API 提供了最轻量、最可靠的方式:GetSystemInfo 返回的 SYSINFO.dwNumberOfProcessors 就是当前系统可见的逻辑核心数(即超线程后的总数)。它不区分物理/逻辑,只反映 OS 调度器能用的线程数。
注意:这个值在 Windows Server 2012+ 或启用了 Core Isolation 的机器上仍准确;但若进程被 CPU 亲和性限制(比如 SetThreadAffinityMask),它不会变——因为它是系统级信息,不是进程级视图。
示例代码片段:
#include <windows.h>
#include <iostream>
int main() {
SYSTEM_INFO si;
GetSystemInfo(&si);
std::cout << "Logical cores: " << si.dwNumberOfProcessors << '\n';
}
Linux/macOS用sysconf查逻辑核心数
POSIX 系统统一用 sysconf(_SC_NPROCESSORS_ONLN) 获取当前在线的逻辑核心数。它返回的是运行时可用数,会受 cgroups、taskset 或 isolcpus 内核参数影响——比如容器里限制了 2 核,这里就返回 2。
立即学习“C++免费学习笔记(深入)”;
常见误用:sysconf(_SC_NPROCESSORS_CONF) 返回的是“配置数”,即 BIOS 启用的总逻辑核心数,哪怕某些核心被 nosmt 关闭了也照算,容易高估。
推荐只用 _SC_NPROCESSORS_ONLN,除非你明确需要理论最大值。
跨平台获取物理核心数要绕开API差异
没有标准 C++ 接口能直接拿到物理核心数。Windows 需解析 GetLogicalProcessorInformation 返回的 LOGICAL_PROCESSOR_RELATIONSHIP 结构,按 RelationProcessorCore 分组计数;Linux/macOS 则得靠读取 /sys/devices/system/cpu/topology/core_siblings_list 或 sysctl hw.physicalcpu(macOS)。
实际建议:
- 优先用第三方库如
hwloc(编译时链接-lhwloc),调用hwloc_get_nbobjs_by_type(topology, HWLOC_OBJ_CORE) - 自己实现时,Windows 下必须遍历所有
RelationProcessorCore并去重计数(同一物理核上的多个逻辑核共享一个GroupMask) - Linux 下别硬解析
/proc/cpuinfo的core id和physical id,不同架构(ARM vs x86)字段含义不一致,topology/core_siblings_list更稳
std::thread::hardware_concurrency() 只能作参考
这个标准库函数理论上返回“推荐的并发线程数”,但它在很多编译器实现里只是简单返回 sysconf(_SC_NPROCESSORS_ONLN) 或 GetSystemInfo().dwNumberOfProcessors,也就是逻辑核心数——且可能返回 0(如编译器未实现或检测失败)。
关键限制:
- 它不保证返回物理核心数
- 在容器或受限环境中可能不准(比如 musl libc 下某些静态链接场景)
- C++11 规范明确说“可返回 0”,不能当作可靠依据
真正需要物理核心数做线程池规划时,别依赖它。
物理核心识别始终是平台相关操作,没有银弹;最容易被忽略的是:同一块 CPU 在不同内核启动参数(如 nosmt)或虚拟化环境(如 KVM + vcpu_count 与 cores 不一致)下,物理/逻辑关系会动态变化,硬编码任何数值都不可靠。


















