2

当前情况:
我正在尝试测量我系统的当前 CPU 利用率(以赫兹为单位)。

我已经查看了解决我的问题的答案,但是我似乎无法使代码正常工作。

这是我当前的代码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()为零。

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

附加信息:
我以前没有使用过 PDH。

4

2 回答 2

4

这是一个PdhAddCoutner()依赖于语言的。你应该PdhAddEnglishCounter()改用。

编辑:您应该在 . 中运行init()的查询和getvalue().

补充说明:

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

我首先认为有一个错字,并在Technet上验证了对象的名称和计数器。

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

关于时序约束

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

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

于 2015-07-25T13:55:08.837 回答
0
/* 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的解决方案(请比我更喜欢他)。

于 2015-07-25T15:01:51.660 回答