Windows平台可用PDH API采集Processor(*)% Processor Time计数器实现逐核利用率监控,需两次采样取差值;Linux平台通过解析/proc/stat中cpuN行的jiffies数据两次采样计算各核busy/total比值得到利用率。
如果您需要在 C++ 程序中实时获取系统中每个 CPU 核心的当前利用率,Windows 平台可借助 Windows Performance Counter API 和 WMI;Linux 平台则可通过解析 /proc/stat 文件并进行两次采样差值计算。以下是适用于不同操作系统的多种实现方法:
一、Windows 平台:使用 PdhCollectQueryData 采集性能计数器
该方法通过 Windows 提供的 PDH(Performance Data Helper)API 访问 Processor(*)% Processor Time 计数器,其中 * 表示每个逻辑处理器,支持逐核采样。需两次调用以计算差值,避免首次返回无效值。
1、调用 PdhOpenQuery 创建性能查询句柄。
2、对每个逻辑处理器索引 i,构造计数器路径 L"\Processor(0)\% Processor Time",将数字替换为 i,调用 PdhAddCounter 添加对应计数器。
立即学习“C++免费学习笔记(深入)
”;
3、调用 PdhCollectQueryData 更新所有计数器数据。
4、等待约 1000 毫秒后再次调用 PdhCollectQueryData。
5、对每个计数器,调用 PdhGetFormattedCounterValue 获取 double 类型的百分比值,注意需调用两次且间隔不小于 1 秒才能获得有效利用率。
二、Windows 平台:使用 GetSystemTimes 获取全局 CPU 时间片
该方法不直接提供每核数据,但可通过 CreateToolhelp32Snapshot 遍历 SYSTEM_INFO.dwNumberOfProcessors 获取核心数,并结合 GetSystemTimes 返回的空闲、内核、用户时间总和,配合多次采样推算各核平均负载趋势。适用于轻量级监控场景,无需管理员权限。
1、调用 GetSystemInfo 获取 dwNumberOfProcessors 值,确定逻辑处理器总数。
2、调用 GetSystemTimes 获取 FILETIME 类型的 idleTime、kernelTime、userTime。
3、转换 FILETIME 为 uint64_t 总 100ns 单位时间戳,计算总活动时间 = kernelTime + userTime - idleTime。
C知道CSDN推出的一款AI技术问答工具下载4、间隔 500ms 后再次调用 GetSystemTimes,计算两次差值比,此值反映整个系统平均 CPU 利用率,非单核独立值。
三、Linux 平台:解析 /proc/stat 计算各逻辑 CPU 利用率
/proc/stat 中以 cpuN 开头的行记录了第 N 个逻辑 CPU 的 user、nice、system、idle、iowait、irq、softirq、steal、guest、guest_nice 十项累计时间(单位:jiffies)。通过两次读取并计算差值,可得出各核利用率。
1、打开 /proc/stat 文件,逐行读取,匹配以 "cpu" 开头且后续字符全为数字的行(如 "cpu0"、"cpu1")。
2、对每行解析出前 10 个无符号整数字段,累加前 3 项(user+nice+system)作为 busy 时间,累加后 7 项(含 idle)作为 total 时间。
3、保存第一次采样的 busy_i 和 total_i 数组,sleep(1) 后执行第二次采样得到 busy_j 和 total_j。
4、对每个核 i,计算利用率 = (busy_j[i] - busy_i[i]) * 100.0 / (total_j[i] - total_i[i]),分母为零时跳过该核,避免浮点异常。
四、Linux 平台:使用 sysconf(_SC_NPROCESSORS_ONLN) + sched_getaffinity 辅助定位
该方法不直接统计利用率,但可用于动态确认当前进程可绑定的活跃 CPU 核心集合,配合 /proc/stat 数据过滤掉离线核心,提升统计准确性。尤其适用于热插拔 CPU 或容器限制场景。
1、调用 sysconf(_SC_NPROCESSORS_ONLN) 获取当前在线逻辑 CPU 总数。
2、声明 cpu_set_t mask,调用 CPU_ZERO(&mask),再调用 sched_getaffinity(0, sizeof(mask), &mask) 获取当前进程 CPU 亲和性掩码。
3、遍历 0 到 CPU_SETSIZE-1,对每个 i 调用 CPU_ISSET(i, &mask),若返回真且 i 4、后续仅对有效核索引读取 /proc/stat 对应行,避免解析不存在或已下线的 cpuN 行导致误判。
