winapi — найти текущее использование процессора в герцах (Windows)

Текущая ситуация:
Я пытаюсь измерить текущую загрузку процессора моей системы в герцах.

Я посмотрел на этот ответ который отвечает на мой вопрос, однако я не могу заставить код работать.

Это мой ток код в 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() это ноль.

Связанные наблюдения:
Я заметил, что значения в a а также i типа PDH_STATUS оба равны нулю? Я предполагаю, что это может быть связано с моим отсутствием значения в CPUUsage, хотя я не уверен, почему функция не будет возвращаться должным образом в эти значения.

Дополнительная информация:
Я не использовал PDH раньше.

2

Решение

Это PdhAddCoutner() является зависимый от языка. Вы должны использовать PdhAddEnglishCounter() вместо.

РЕДАКТИРОВАТЬ: И вы должны иметь минимальную задержку (500 мс) между запросом, запущенным в init() и запрос в getvalue(),

Дополнительные объяснения:

Запустив свой код в моей системе Windows 8.1, оказалось, что в init(), статус i вернулся был PDH_CSTATUS_NO_OBJECT, что означает, что он не нашел объект «Процессор (_Total)».

Сначала я подумал, что произошла опечатка, и проверил название объекта и счетчик на Technet.

Из любопытства я запустил оригинальную команду windows perfmon.exe и заметил, что все объекты и счетчик были переведены на мой родной язык. Запуск вашего кода с использованием имени счетчика на родном языке дал мне правильный результат.

О временном ограничении

Как только проблема с языком решена, пошагово отлаживая, я получил значимые значения использования моего процессора. Но как только я убрал точки останова, я получил 0 или 100.

Так что я немного углубился в этом вопросе, чтобы выяснить, поддержка Microsoft что процентные ставки требуют минимальных задержек между двумя последовательными запросами. Однажды я добавил Sleep(1000) при выходе из init я снова получил значимые значения загрузки процессора.

3

Другие решения

/* 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;
}
}

Никакой уродливой статики, проверки статуса, использования экземпляров вместо глобальных, минимального включения, сохранения даже без определения юникода, решения Christophe (плз скорее его голосую, чем меня) встроенный.

0

По вопросам рекламы [email protected]