c++ - 获取多处理器的 Windows CPU 利用率的正确方法
问题描述
我想要实现的是我可以获得每个 CPU 的利用率(我有 4 个 CPU 核心,所以我希望我可以resmon.exe
像TaskManager.exe
我已经阅读了一些关于如何通过对 CPU 时间进行数学计算来获得处理器利用率的问题。我试图用它NtQuerySystemInformation
来获取必要的数据。
#include <windows.h>
#include <vector>
#include <iostream>
#include <winternl.h>
#pragma comment(lib, "Ntdll.lib")
typedef struct
_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_R {
LARGE_INTEGER IdleTime;
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER DpcTime;
LARGE_INTEGER InterruptTime;
ULONG InterruptCount;
} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_R;
static long long toInteger(LARGE_INTEGER const & integer)
{
#ifdef INT64_MAX // Does the compiler natively support 64-bit integers?
return integer.QuadPart;
#else
return (static_cast<long long>(integer.HighPart) << 32) | integer.LowPart;
#endif
}
class CPU
{
public:
uint64_t prev_idle = 0;
uint64_t prev_ker = 0;
uint64_t prev_user = 0;
uint64_t cur_idle = 0;
uint64_t cur_ker = 0;
uint64_t cur_user = 0;
double get()
{
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_R *a = new SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_R[4];
// 4 is the total of CPU (4 cores)
NtQuerySystemInformation(SystemProcessorPerformanceInformation, a, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_R) * 4, NULL);
prev_idle = cur_idle;
prev_ker = cur_ker;
prev_user = cur_user;
cur_idle = 0;
cur_ker = 0;
cur_user = 0;
// 4 is the total of CPU (4 cores)
// Sum up the SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_R array so I can get the utilization from all of the CPU
for (int i = 0; i < 4; ++i)
{
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_R b = a[i];
cur_idle += toInteger(b.IdleTime);
cur_ker += toInteger(b.KernelTime);
cur_user += toInteger(b.UserTime);
}
std::cout << "Cur idle " << cur_idle << '\n';
std::cout << "Cur ker " << cur_ker << '\n';
std::cout << "Cur user " << cur_user << '\n';
uint64_t delta_idle = cur_idle - prev_idle;
uint64_t delta_kernel = cur_ker - prev_ker;
uint64_t delta_user = cur_user - prev_user;
std::cout << "Delta idle " << delta_idle << '\n';
std::cout << "Delta ker " << delta_kernel << '\n';
std::cout << "Delta user " << delta_user << '\n';
uint64_t total_sys = delta_kernel + delta_user;
uint64_t kernel_total = delta_kernel - delta_idle;
delete[] a;
// return (total_sys - delta_idle) * 100.0 / total_sys;
return (kernel_total + delta_user) * 100.0 / total_sys;
}
};
int main()
{
CPU a;
std::cout << "starting" << '\n';
while(1)
{
std::cout << a.get() << '\n';
Sleep(1000);
}
return 0;
}
为了获得单个 CPU 利用率,我不必对所有 CPU 求和,只需选择一个SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_R
数组元素即可。
我的问题是
- 我做对了吗?因为当我在 TaskManager.exe 中检查我的程序的 CPU 利用率时,它有些不同。
- 除了使用之外还有什么更好的方法
NtQuerySystemInformation
(因为微软已经提到“NtQuerySystemInformation 在未来的 Windows 版本中可能会被更改或不可用。应用程序应该使用本主题中列出的替代功能。”)?
解决方案
推荐阅读
- javascript - 如何根据请求的百分比来操作节点服务器响应?
- python - 在 Python 中运行程序时输入命令名称 点击
- javascript - 通过 Node.js 从 Firestore 实时更新
- python - Python Pandas 丢弃连续的数据帧,但末尾的句点 (.) 是差异化因素
- r - 使用 Highcharter 的 3D 饼图
- android - 无法将使用 JVM 目标 1.8 构建的字节码内联到使用 JVM 目标 1.6 构建的字节码中,但不影响
- angular - 为什么我无法在我的简单 CRM Angular Web 应用程序中显示成功消息?
- php - Symfony 表单和 json 对象验证
- php - mysql 创建两个精确的行
- python - Python OOP、类和实例