我们在开发服务程序时,有时需要反馈服务器CPU各核心的当前使用率情况,观察负载是否均衡。
在Windows系统,我们可以使用以下API:
API | 说明 |
---|---|
PdhOpenQuery | 创建一个查询句柄,用于收集性能统计数据 |
PdhAddEnglishCounter | 将需要查询的处理器描述信息(英语格式,用以规避多语言问题)添加到查询列表 |
PdhCollectQueryData | 收集查询的原始数据 |
PdhGetFormattedCounterValue | 将已收集的原始数据转换为可显示的格式 |
PdhCloseQuery | 关闭查询句柄 |
以下为测试程序,程序向控制台输出每个逻辑核心的CPU使用率。其中0%为最小使用率,100%为最大使用率。
#include <thread>
#include <Pdh.h> // 引入相关API的头文件
#pragma comment(lib, "pdh.lib") // 关联库文件
// 设置一个查询数量的最大值
#define MAX_QUERY_CORES 1024
int main(int argc, char **argv) {
int num_query_cores = (int)std::thread::hardware_concurrency(); // 获取系统逻辑核心数
HQUERY hQuery = NULL;
HCOUNTER hCounters[MAX_QUERY_CORES];
if (num_query_cores > MAX_QUERY_CORES) {
num_query_cores = MAX_QUERY_CORES;
}
// 创建查询句柄
PDH_STATUS status = PdhOpenQuery(nullptr, 0, &hQuery);
if (status != ERROR_SUCCESS) {
printf("invoke PdhOpenQuery failed, status = 0x%X\n", status);
return 1;
}
// 将查询的每一个逻辑核心添加到查询列表
for (int i = 0; i < num_query_cores; ++i) {
TCHAR buf[PDH_MAX_COUNTER_PATH];
swprintf_s(buf, TEXT("\\Processor(%d)\\%% Processor Time"), i);
status = PdhAddEnglishCounter(hQuery, buf, 0, &hCounters[i]);
if (status != ERROR_SUCCESS) {
printf("invoke PdhAddCounter failed, status = 0x%X\n", status);
return 1;
}
}
// 初始化统计数据
PdhCollectQueryData(hQuery);
// 测试查询若干次
printf("========== Test Begin ==========\n");
int test_query_count = 10;
while (test_query_count--) {
// 等待1秒
std::this_thread::sleep_for(std::chrono::seconds(1));
// 获取1秒间隔内的统计数据
status = PdhCollectQueryData(hQuery);
if (status != ERROR_SUCCESS) {
printf("invoke PdhCollectQueryData failed, status = 0x%X\n", status);
return 1;
}
printf("---------- CPU Usage ----------\n");
for (int i = 0; i < num_query_cores; ++i) {
DWORD ret;
PDH_FMT_COUNTERVALUE value;
// 获取格式化后的结果
status = PdhGetFormattedCounterValue(hCounters[i], PDH_FMT_DOUBLE | PDH_FMT_NOCAP100, &ret, &value);
if (status != ERROR_SUCCESS) {
printf("invoke PdhGetFormattedCounterValue failed, status = 0x%X\n", status);
continue;
}
// 结果为CPU使用率的百分数,0为最小值,100为最大值
int percentage = (int)value.doubleValue;
printf("CPU %02d usage: %3d%%\n", i, percentage);
}
}
printf("========== Test End ==========\n");
// 关闭查询句柄
PdhCloseQuery(hQuery);
hQuery = NULL;
return 0;
}