c++中如何获取系统CPU核心数_c++ std::thread硬件并发数【详解】
技术百科
冰火之心
发布时间:2026-01-27
浏览: 次 std::thread::hardware_concurrency() 不可靠,仅返回启发式估计值,可能为0或逻辑线程数而非物理核心数;应优先用sysconf(_SC_NPROCESSORS_ONLN)(Linux/macOS)或GetActiveProcessorCount(Windows)获取真实逻辑CPU数。
std::thread::hardware_concurrency() 返回值到底靠不靠谱
std::thread::hardware_concurrency() 是 C++11 起提供的标准方式,用于查询系统“建议的”硬件线程数。但它返回的是 启发式估计值,不是精确核心数,更不是当前可用逻辑 CPU 数。
常见现象:在某些虚拟机、容器或启用了 CPU 限制的环境中,它可能返回 0;在超线程开启的 Intel CPU 上,它通常返回逻辑处理器总数(如 8 核 16 线程 → 返回 16),而非物理核心数。
- 它不区分物理核心和逻辑线程(Hyper-Threading / SMT)
- 它不感知 cgroups、CPU affinity 或 runtime 限制(比如
docker run --cpus=2) - 返回
0表示“无法确定”,此时不应当作 1 使用,而应 fallback 到其他探测方式
跨平台获取真实逻辑 CPU 数(推荐实操方案)
要拿到当前进程实际能调度到的逻辑 CPU 总数,优先用 OS 原生 API,再 fallback 到 std::thread::hardware_concurrency()。
Linux/macOS 下最可靠的是 sysconf(_SC_NPROCESSORS_ONLN)(POSIX),Windows 下用 GetActiveProcessorCount(ALL_PROCESSOR_GROUPS)(Win10 1607+)或 GetSystemInfo().dwNumberOfProcessors(兼容旧版)。
#include#ifdef _WIN32 #include #else #include #endif int get_logical_cpu_count() { #ifdef _WIN32 // Win10 1607+ 推荐,考虑 processor groups if (GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetActiveProcessorCount")) { return static_cast (GetA ctiveProcessorCount(ALL_PROCESSOR_GROUPS)); } // fallback SYSTEM_INFO si; GetSystemInfo(&si); return static_cast
(si.dwNumberOfProcessors); #else long n = sysconf(_SC_NPROCESSORS_ONLN); return (n > 0) ? static_cast (n) : 1; #endif } int main() { std::cout << "Logical CPU count: " << get_logical_cpu_count() << "\n"; std::cout << "std::thread::hardware_concurrency(): " << std::thread::hardware_concurrency() << "\n"; }
如何区分物理核心数和逻辑线程数
仅靠标准 C++ 无法做到。必须调用平台特定接口:
- Linux:读取
/sys/devices/system/cpu/cpu*/topology/core_id并去重统计(需 root 权限非必需,但部分容器中不可读) - Linux(无 root):解析
/proc/cpuinfo中cpu cores(每物理 CPU 的核心数) ×physical id数量,或用lscpu | grep 'Core(s) per socket'+'Socket(s)' - macOS:
sysctl -n hw.physicalcpu和hw.logicalcpu - Windows:WMI 查询
Win32_Processor的NumberOfCores和NumberOfLogicalProcessors
注意:std::thread::hardware_concurrency() 从不提供物理核心数 —— 它的设计目标就是“适合并行任务的线程上限”,即逻辑线程数。
实际写并发程序时该用哪个值
绝大多数场景下,你应该用 get_logical_cpu_count()(或 sysconf(_SC_NPROCESSORS_ONLN))作为线程池大小上限,而不是 std::thread::hardware_concurrency()。
- 当程序受 CPU 密集型负载主导时,线程数 ≈ 逻辑 CPU 数是最优起点
- 若混合 I/O,可适当上浮(如 ×1.5),但需压测验证
- 在容器中运行时,
/sys/fs/cgroup/cpuset/cpuset.effective_cpus才是真实可用 CPU 列表,需解析该文件(Linux only) -
std::thread::hardware_concurrency()唯一稳妥用途是:作为 fallback,且必须检查是否为 0
物理核心数只在极少数场景有用,比如绑定线程到独占物理核避免超线程干扰(real-time audio、低延迟交易),这时你得自己解析拓扑,不能依赖标准库。
# ai
# 的是
# 才是
# 它不
# 能为
# windows
# 但它
# 不应
# 而非
# 只在
# mac
# win10
# linux
# docker
# 并发
# macos
# c++
# 接口
# 线程
# Thread
# cad
# ios
# 处理器
# 查询系统
# 虚拟机
# 超线程
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- php8.4xdebug无法调试怎么办_php8.
- php增删改查需要哪些扩展_开启mysqli或pd
- c++如何连接Redis c++ hiredis库
- Win11怎么硬盘分区 Win11新建磁盘分区详细
- 如何使用Golang table-driven基准
- c++20的std::format怎么用 比pri
- 如何使用Golang配置安全开发环境_防止敏感信息
- 如何使用 Python 合并文件夹内多个 Exce
- 如何在Golang中捕获结构体方法错误_Golan
- Win11资源管理器卡顿怎么办 Win11文件资源
- php转mp4怎么设置帧率_调整php生成mp4视
- 跨文件调用类方法怎么用_php作用域操作符与自动加
- WindowsUSB驱动安装异常怎么办_USB驱动
- 如何在Golang中定义接口_抽象方法和多态实现
- Win10如何更改网络连接_Windows10以太
- Win11怎么设置单手模式_Win11触控键盘布局
- Win11怎么设置快速访问_Windows11文件
- 如何使用Golang反射创建map对象_动态生成键
- 如何使用Golang sync.Map实现并发安全
- c++如何获取map中所有的键_C++遍历键值对提
- Python爬虫项目实战教程_Scrapy抓取与存
- Win11怎么设置虚拟键盘_打开Win11屏幕键盘
- 如何在 Python 中将 ISO 8601 时间
- php怎么下载安装后设置错误日志_phpini l
- Python邮件系统自动化教程_批量发送解析与模板
- 如何在 Django 中修改用户密码后保持会话不丢
- MAC怎么使用表情符号面板_MAC Emoji快捷
- Mac怎么查看活动监视器_理解Mac进程和资源占用
- 如何将文本文件中的竖排字符串转换为横排字符串
- Windows10怎样设置家长控制_Windows
- 作用域操作符会影响性能吗_php静态调用性能分析【
- Win10如何更改开机密码_Windows10登录
- PHP 中如何在函数内持久化修改引用变量的指向
- 如何使用Golang实现基本类型比较_Golang
- c++中如何使用std::variant_c++1
- 微信短链接怎么还原php_用浏览器开发者工具抓包获
- PHP主流架构如何做单元测试_工具与流程【详解】
- Win11怎么关闭触控板_Win11笔记本禁用触摸
- Win11开机速度慢怎么优化_Win11系统启动加
- 如何更改Windows资源管理器的默认启动位置?(
- php转exe用什么工具打包快_高效打包软件推荐【
- php订单日志怎么按金额排序_php按订单金额排序
- 如何用正则表达式精确匹配“start”到“end”
- LINUX如何查看文件类型_Linux中file命
- 如何使用Golang实现云原生应用弹性伸缩_自动应
- Win11如何关闭小娜Cortana Win11禁
- 如何在Golang中实现微服务服务拆分_Golan
- Win10怎样设置闹钟贪睡时间 Win10闹钟贪睡
- PHP cURL GET请求:正确设置请求头与身份
- Windows怎样关闭开始菜单推荐广告_Windo


QQ客服