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
<h3>Linux/macOS用<code>sysconf</code>查逻辑核心数</h3>
<p>POSIX 系统统一用 <code>sysconf(_SC_NPROCESSORS_ONLN)</code> 获取当前在线的逻辑核心数。它返回的是运行时可用数,会受 <code>cgroups</code>、<code>taskset</code> 或 <code>isolcpus</code> 内核参数影响——比如容器里限制了 2 核,这里就返回 2。</p>
<p>常见误用:<code>sysconf(_SC_NPROCESSORS_CONF)</code> 返回的是“配置数”,即 BIOS 启用的总逻辑核心数,哪怕某些核心被 <code>nosmt</code> 关闭了也照算,容易高估。</p>
<p>推荐只用 <code>_SC_NPROCESSORS_ONLN</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>
<h3>跨平台获取物理核心数要绕开API差异</h3>
<p>没有标准 C++ 接口能直接拿到物理核心数。Windows 需解析 <code>GetLogicalProcessorInformation</code> 返回的 <code>LOGICAL_PROCESSOR_RELATIONSHIP</code> 结构,按 <code>RelationProcessorCore</code> 分组计数;Linux/macOS 则得靠读取 <code>/sys/devices/system/cpu/topology/core_siblings_list</code> 或 <code>sysctl hw.physicalcpu</code>(macOS)。</p>
<p>实际建议:</p>
<ul>
<li>优先用第三方库如 <code>hwloc</code>(编译时链接 <code>-lhwloc</code>),调用 <code>hwloc_get_nbobjs_by_type(topology, HWLOC_OBJ_CORE)</code>
</li>
<li>自己实现时,Windows 下必须遍历所有 <code>RelationProcessorCore</code> 并去重计数(同一物理核上的多个逻辑核共享一个 <code>GroupMask</code>)</li>
<li>Linux 下别硬解析 <code>/proc/cpuinfo</code> 的 <code>core id</code> 和 <code>physical id</code>,不同架构(ARM vs x86)字段含义不一致,<code>topology/core_siblings_list</code> 更稳</li>
</ul>
<h3>std::thread::hardware_concurrency() 只能作参考</h3>
<p>这个标准库函数理论上返回“推荐的并发线程数”,但它在很多编译器实现里只是简单返回 <code>sysconf(_SC_NPROCESSORS_ONLN)</code> 或 <code>GetSystemInfo().dwNumberOfProcessors</code>,也就是逻辑核心数——且可能返回 0(如编译器未实现或检测失败)。</p>
<p>关键限制:</p>
<ul>
<li>它不保证返回物理核心数</li>
<li>在容器或受限环境中可能不准(比如 musl libc 下某些静态链接场景)</li>
<li>C++11 规范明确说“可返回 0”,不能当作可靠依据</li>
</ul>
<p>真正需要物理核心数做线程池规划时,别依赖它。</p>
<p>物理核心识别始终是平台相关操作,没有银弹;最容易被忽略的是:同一块 CPU 在不同内核启动参数(如 <code>nosmt</code>)或虚拟化环境(如 KVM + <code>vcpu_count</code> 与 <code>cores</code> 不一致)下,物理/逻辑关系会动态变化,硬编码任何数值都不可靠。</p></iostream></windows.h>C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










