需通过windows性能计数器(pdh)、wmi或ntquerysysteminformation三种方式动态获取进程cpu占用率:pdh需两次采样差分计算;wmi直接读取预计算的percentprocessortime;nt接口则结合进程时间与系统总时间手动归一化。

如果您需要在 C++ 程序中动态获取指定进程当前时刻的 CPU 占用百分比,则不能依赖静态快照或系统平均值,而需通过 Windows 性能计数器(Performance Counters)采集两个时间点的处理器时间差并归一化计算。以下是实现该功能的具体步骤:
一、使用 PDH 接口查询进程 CPU 使用率
PDH(Performance Data Helper)是 Windows 提供的封装 API,用于安全、高效地读取性能计数器数据。它支持以毫秒级精度采样,并可直接绑定到特定进程 ID 对应的 "% Processor Time" 计数器实例。
1、调用 PdhOpenQuery 创建一个性能查询句柄。
2、构造计数器路径字符串,格式为 \Process(process_name)\% Processor Time 或使用 PID 动态生成:通过 \Process(process_id)\% Processor Time(需确保进程名含下划线转义,如 "chrome#1")。
3、调用 PdhAddCounter 添加该路径对应的计数器到查询中。
4、执行首次采样:PdhCollectQueryData,此调用仅初始化计数器,不返回有效值。
5、等待至少 100 毫秒后,再次调用 PdhCollectQueryData,随后使用 PdhGetFormattedCounterValue 获取 double 类型的 CPU 百分比数值。
二、通过 WMI 查询 Win32_PerfFormattedData_PerfProc_Process 类
WMI 提供面向对象的性能数据访问方式,Win32_PerfFormattedData_PerfProc_Process 类已预计算好每个进程的 CPU 使用率(PercentProcessorTime 属性),无需手动差分,适合单次低频查询。
1、初始化 COM 库:CoInitializeEx(nullptr, COINIT_MULTITHREADED)。
2、连接 WMI 命名空间:IWbemLocator::ConnectServer,目标为 ROOTCIMV2。
3、设置安全上下文:CoSetProxyBlanket 配置 IWbemServices 接口代理。
4、执行 WQL 查询:SELECT Name, PercentProcessorTime, IDProcess FROM Win32_PerfFormattedData_PerfProc_Process WHERE IDProcess = X,其中 X 替换为目标进程 PID。
5、遍历 IEnumWbemClassObject 枚举结果,提取 PercentProcessorTime 字段值,该值即为 0–100 范围内的实时整数百分比。
三、读取 NtQuerySystemInformation 中的 SystemProcessInformation
该方法绕过高层 API,直接调用未公开但稳定的 NT 内核接口,获取所有进程的内核态与用户态执行时间,再结合系统总时间差计算 CPU 占用率,精度高且无额外依赖。
1、加载 ntdll.dll 并获取 NtQuerySystemInformation 函数地址。
2、分配足够缓冲区,调用该函数传入 SystemProcessInformation 类型,获取包含所有进程信息的链表结构。
3、遍历链表,定位目标 PID 对应的 SYSTEM_PROCESS_INFORMATION 条目,读取其 KernelTime 和 UserTime 字段(单位为 100 纳秒)。
4、在间隔 Δt 后再次调用,获取新时间值;同时调用 GetSystemTimes 获取对应时段的空闲、内核、用户总时间增量。
5、按公式计算:(ΔKernelTime + ΔUserTime) / (ΔTotalSystemTime) * 100,结果即为该进程在 Δt 内的平均 CPU 百分比。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











