【问题标题】:C++ - Find current CPU usage in Hertz (Windows)C++ - 以赫兹 (Windows) 为单位查找当前 CPU 使用率
【发布时间】:2015-07-25 12:10:05
【问题描述】:

现状:
我正在尝试以 Hertz 为单位测量我系统的当前 CPU 利用率。

我查看了this answer,它解决了我的问题,但我似乎无法使代码正常工作。

这是我目前在main.cpp 中的代码(来自答案):

#include <Pdh.h>
#include <PdhMsg.h>
#include <Windows.h>

static PDH_HQUERY cpuQuery;
static PDH_HCOUNTER cpuTotal;

void init()
{
    PDH_STATUS a = PdhOpenQuery(NULL, NULL, &cpuQuery);
    PDH_STATUS i = PdhAddCounter(cpuQuery, L"\\Processor(_Total)\\% Processor Time", NULL, &cpuTotal);
    PdhCollectQueryData(cpuQuery);
}

double getCurrentValue()
{
    init();
    PDH_FMT_COUNTERVALUE counterVal;

    PdhCollectQueryData(cpuQuery);
    PdhGetFormattedCounterValue(cpuTotal, PDH_FMT_DOUBLE, NULL, &counterVal);
    return counterVal.doubleValue;
}

int main()
{
    double CPUUsage = getCurrentValue();
}

问题:
getCurrectValue() 返回的值为零。

相关观察:
我观察到,PDH_STATUS 类型的 ai 中的值都为零?我推测这可能与我在 CPUUsage 中缺少值有关,尽管我不确定为什么该函数无法正确返回这些值。

其他信息:
我以前没用过PDH。

【问题讨论】:

  • 如果两种状态都为 0,尽管如此,CPU 使用率为零,这可能是因为显示 cpu 速率所需的最小延迟(请参阅下面我的答案的编辑)。 .
  • 只是几个澄清:(1) CPU 使用周期/秒在现代处理器中没有任何意义,因此 pdh 给出处理器的百分比; (2) pdh 命令提供基于操作系统活动而不是实际硬件性能计数器的估计值。

标签: c++ winapi cpu-usage pdh


【解决方案1】:

这是一个PdhAddCoutner()取决于语言。您应该改用 PdhAddEnglishCounter()

编辑:init() 中运行的查询和getvalue() 中的查询之间应该有一个最小延迟(500 毫秒)。

补充说明:

在我的windows 8.1系统上运行你的代码,结果发现在init(),返回的状态iPDH_CSTATUS_NO_OBJECT,这意味着它没有找到对象“Processor(_Total)”。

我一开始以为有错字,并在Technet 上验证了对象的名称和计数器。

出于好奇,我运行了原来的 windows 命令perfmon.exe 并注意到所有的对象和计数器都被翻译成我的母语。使用计数器的母语名称运行代码给了我正确的结果。

关于时间限制

解决语言问题后,逐步调试我得到了有意义的 CPU 使用率值。但是一旦我删除了断点,我得到了 0 或 100。

所以我在这个问题上进一步挖掘了microsoft support 的百分比率需要两个连续查询之间的一些最小延迟。一旦我在 init 退出时添加了Sleep(1000),我又得到了有意义的 CPU 使用率值。

【讨论】:

    【解决方案2】:
    /* Needed windows definitions by following header */
    #include <windef.h>
    /* Windows performance data helper */
    #include <Pdh.h>
    
    /* Storage of PDH query and associated cpu counter */
    struct cpu_counter{
        PDH_HQUERY query;
        PDH_HCOUNTER counter;
    };
    
    /* Initialize query & counter */
    int cpu_counter_init(struct cpu_counter* pcc)
    {
        if(PdhOpenQueryA(NULL, 0, &pcc->query) != ERROR_SUCCESS)
            return -1;
        if(PdhAddEnglishCounterA(pcc->query, "\\Processor(_Total)\\% Processor Time", 0, &pcc->counter) != ERROR_SUCCESS || PdhCollectQueryData(pcc->query) != ERROR_SUCCESS)
        {
            PdhCloseQuery(pcc->query);
            return -2;
        }
        return 0;
    }
    
    /* Fetch data from query and evaluate current counter value */
    int cpu_counter_get(struct cpu_counter* pcc)
    {
        PDH_FMT_COUNTERVALUE counter_val;
        if(PdhCollectQueryData(pcc->query) != ERROR_SUCCESS || PdhGetFormattedCounterValue(pcc->counter, PDH_FMT_LONG, NULL, &counter_val) != ERROR_SUCCESS)
            return -1;
        return counter_val.longValue;
    }
    
    /* Close all counters of query and query itself at the end */
    void cpu_counter_close(struct cpu_counter* pcc)
    {
        if(pcc->query != NULL)
        {
            PdhCloseQuery(pcc->query);
            pcc->query = NULL;
        }
    }
    

    没有丑陋的静态,状态检查,使用实例而不是全局,最小包含,即使没有 unicode 定义也可以保存,内置 Christophe 的解决方案(请比我更喜欢他)。

    【讨论】:

      猜你喜欢
      • 2013-06-27
      • 2016-08-15
      • 1970-01-01
      • 2014-04-20
      • 1970-01-01
      • 1970-01-01
      • 2018-12-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多