用PDH库获取CPU使用率(源码)

1、概述

PDH工作原理:

第一次采集:获取当前CPU的"累计运行时间"

第二次采集:一段时间后,再次获取累计运行时间

计算差值:

用第二次的值,减去第一次的值,得出这段时间内的活跃时间占比。

所以会有如下结论:

调用间隔 返回值含义 是否「实时」
1 秒 过去 1 秒的 CPU 使用率 ✅ 实时
5 秒 过去 5 秒的平均使用率 ✅ 基本实时
30 秒 过去 30 秒的平均使用率 ⚠️ 略有延迟
30 分钟 过去 30 分钟的平均使用率 ❌ 不实时,是历史平均

2、源码

2.1、调用示例

cpp 复制代码
    CCpuUsageUtil cpu;
    if (!cpu.Init())
    {
        printf("初始化失败!可能是计数器名称错误(中文系统?)\n");
        return -1;
    }
    cpu.GetUsage();
    Sleep(2000);
    int usage = cpu.GetUsage();
    printf("CPU 使用率: %d%%\n", usage);

2.2、源码

cpp 复制代码
#ifndef Cpu_Usage_h_
#define Cpu_Usage_h_

#include <pdh.h>
#include <pdhmsg.h>

#define MAX_RAW_VALUES          20

// \Processor(_Total):表示所有CPU核心的总和
// % Processor Time:表示CPU使用率(百分比)
const wchar_t g_szCounterName[] = L"\\Processor Information(_Total)\\% Processor Time";

typedef struct _tag_PDHCounterStruct {
    HCOUNTER hCounter;      // Handle to the counter - given to use by PDH Library
    //int nNextIndex;         // element to get the next raw value
    //int nOldestIndex;       // element containing the oldes raw value
    //int nRawCount;          // number of elements containing raw values
    //PDH_RAW_COUNTER a_RawValue[MAX_RAW_VALUES]; // Ring buffer to contain raw values
} PDHCOUNTERSTRUCT, *PPDHCOUNTERSTRUCT;

class CCpuUsageUtil
{
public:
    CCpuUsageUtil();
    virtual ~CCpuUsageUtil();
    BOOL Init();
    void Unit();
    int GetUsage();

protected:
    PPDHCOUNTERSTRUCT  m_pCounterStruct;
    HQUERY  m_hQuery;
};

#endif
cpp 复制代码
#include "CpuUsage.h"

#pragma comment(lib,"PDH.lib")

CCpuUsageUtil::CCpuUsageUtil()
{
    m_hQuery = NULL;
    m_pCounterStruct = NULL;
}

CCpuUsageUtil::~CCpuUsageUtil()
{
    Unit();
}

BOOL CCpuUsageUtil::Init()
{
    if (ERROR_SUCCESS != PdhOpenQuery(NULL, 0, &m_hQuery))
    {
        return FALSE;
    }

    m_pCounterStruct = new PDHCOUNTERSTRUCT;
    PDH_STATUS pdh_status = PdhAddCounter(m_hQuery, g_szCounterName, (DWORD)m_pCounterStruct, &(m_pCounterStruct->hCounter));
    if (ERROR_SUCCESS != pdh_status)
    {
        Unit();
        return FALSE;
    }

    PdhCollectQueryData(m_hQuery);
    return TRUE;
}

void CCpuUsageUtil::Unit()
{
    PdhCloseQuery(m_hQuery);
    m_hQuery = nullptr;
    if (m_pCounterStruct)
    {
        delete m_pCounterStruct;
        m_pCounterStruct = nullptr;
    }
}

int CCpuUsageUtil::GetUsage()
{
    PDH_FMT_COUNTERVALUE pdhFormattedValue;
    PdhCollectQueryData(m_hQuery);
    if (ERROR_SUCCESS != PdhGetFormattedCounterValue(m_pCounterStruct->hCounter, PDH_FMT_LONG, NULL, &pdhFormattedValue))
    {
        return 0;
    }

    return pdhFormattedValue.longValue;
}
相关推荐
SNAKEpc1213821 分钟前
OpenGL(十五)- 着色器语言GLSL
c语言·c++·线性代数·算法·矩阵·图形渲染·着色器
Rabitebla43 分钟前
C++11 新特性详解(一):列表初始化、initializer_list 与右值引用
java·开发语言·数据结构·c++·算法·leetcode·list
MC皮蛋侠客2 小时前
TDengine C++ 系列(11):性能模型与调优——从测量到优化
c++·php·tdengine
兔兔兔兔12 小时前
记录C++ 3
开发语言·c++
代码地平线2 小时前
C++类与对象(中):默认成员函数与日期类实战
c++·笔记·算法
hansang_IR2 小时前
【题解】可持久化区间仿射区间和(Persistent Range Affine Range Sum)
c++·算法·线段树
瑞码空间3 小时前
01背包:动态规划的Hello World
c++·算法·0/1背包问题
鱼子星_3 小时前
【C++】反向迭代器:反向迭代器的底层认识与模拟实现
开发语言·c++·笔记·stl
郝学胜-神的一滴3 小时前
[简化版 GAMES 104] 现代游戏引擎 05:游戏引擎世界构建核心机制深度解析
c++·程序人生·unity·游戏引擎·计算机图形学·opengl
Darkwanderor3 小时前
C++的流简介和简单使用
开发语言·c++