Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Вычисление текущей загрузки процессора  (Прочитано 24648 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Mike_I
Участник

ru
Offline Offline
Пол: Мужской
Mike


« : 05-10-2006 13:50 » 

Привет, народ.

Подскажите пути реализации задачи из сабжа.
В инете и на форуме нарыл, что надо использовать функцию NtQuerySystemInformation. В MSDN'е написано через нее можно получить список всех процессов которые запущены на компе. Это понятно. Но как имея этот список вычислить загрузку процессора??? Или это делается вообще по другому?  Быть такого не может
« Последнее редактирование: 10-12-2007 18:01 от Алексей1153++ » Записан

Nothing fails like success.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 05-10-2006 14:15 » 

кстати, тоже интересно было бы узнать...
Записан

Sands
Помогающий

ua
Offline Offline

« Ответ #2 : 05-10-2006 14:33 » 

вот что я в свое время нарыл и удачно использовал:
Код:
#include <stdio.h>
#include <pdh.h>
#include <conio.h>

/*****************************************************************************/
/********                                                             ********/
/********           не забудьте включить в проект "pdh.lib"           ********/
/********                                                             ********/
/********    Project -> Settings -> Link -> Object/Library Modules    ********/
/********                                                             ********/
/*****************************************************************************/


/*****************************************************************************/
/**********                                                         **********/
/**********            PDH - performance data helper                **********/
/**********                                                         **********/
/*****************************************************************************/


/************************** Описание наших функций ***************************/

#define PDH_ERROR -1

// Функция инициализирует PDH (performance data helper)
PDH_STATUS pdh_Init (HQUERY &hQuery, HCOUNTER &hCounter);


// Функция возвращает в случае удачи загруженность проца, в противном случае PHG_ERROR (-1)
int GetCPUUsage (HQUERY hQuery, HCOUNTER hCounter, PDH_STATUS &pdhStatus);


// Функция анинициализирует PDH
void pdh_Uninit (HQUERY hQuery, HCOUNTER hCounter);


// Функция показывает сообщение об ошибке
void ShowErrorMessage(PDH_STATUS pdhStatus);


// хмм... в названии функции все сказано!
void begin();

/****************************************************************************/


void main(void)
{
    begin();
   
    printf(TEXT("Press any key to continue")); // нажмите "any key" на клавиатуре :P
    while (!_getch()); // ждем, пока юзверь не "клацнет" "any key"
}

void begin()
// хмм... в названии функции все сказано!
{
    PDH_STATUS  pdhStatus      = 0;

    HQUERY hQuery;
    HQUERY hCounter;
    int iUsage = 0;
    pdhStatus = pdh_Init(hQuery, hCounter); // инициализируем PDH

 // если не произошел облом с иницализации PDH, то
    if ( pdhStatus == ERROR_SUCCESS )
    {
 // пока юзверь не зажмет клавишу Esc, то
        while (GetKeyState(VK_ESCAPE) >= 0)
        {
 // получаем загруженность проца
            iUsage = GetCPUUsage(hQuery, hCounter, pdhStatus);

 // если не произошла ошибка (т.е. не вернулось значение PHG_ERROR)
            if (iUsage != PDH_ERROR)
                printf("%3i%%\r\n", iUsage); // выводим значение
            else // а если произошла ошибка, то

// показываем сообщение, что произошла ошибка такая-то
            ShowErrorMessage(pdhStatus);

            Sleep(500); // ждем 0.5 секунд(ы)
        }

// если юзверь все-таки клацнул Esc, то флаг ему в руки :)
        pdh_Uninit(hQuery, hCounter); // заканчиваем работу с PDH
    }
    else // если произошла ошибка при инициализации PDH
        ShowErrorMessage(pdhStatus); // показываем Еррорное сообщение
}

void ShowErrorMessage(PDH_STATUS pdhStatus)
// Сама функция показа сообщения об ошибке
{
    LPSTR szMessage = NULL;

// грузим строку с ошибкой в szMessage. Память выделит функция
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                    FORMAT_MESSAGE_FROM_HMODULE,
                    GetModuleHandle("PDH.DLL"), pdhStatus,
                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                    szMessage, 0, NULL);

    printf("Error №%i:  %s\r\n", pdhStatus, szMessage); // показываем ошибку

    LocalFree(szMessage); // очищаем буфер
}

PDH_STATUS pdh_Init(HQUERY &hQuery, HCOUNTER &hCounter)
// инициализируем PDH
{
    PDH_STATUS  pdhResult   = 0;
    TCHAR       szCounterPath[1024];
    DWORD       dwPathSize  = 1024;
    PDH_COUNTER_PATH_ELEMENTS pe;
    DWORD       dwType      = 0;
   
    pdhResult = PdhOpenQuery( NULL, 0, &hQuery ); // запрос на открытие PDH
   
    if ( pdhResult != ERROR_SUCCESS ) // если была ошибка, то
        return pdhResult; // выходим, возвращая номер ошибки

    pe.szMachineName     = 0l;
    pe.szObjectName      = "Processor";
    pe.szInstanceName    = "_Total";
    pe.szParentInstance  = NULL;
    pe.dwInstanceIndex   = 0;
    pe.szCounterName     = "% Processor Time";

// создаем путь к счетчику PDH
    pdhResult = PdhMakeCounterPath(&pe, szCounterPath, &dwPathSize, 0);

    if (pdhResult != ERROR_SUCCESS) // если была ошибка, то
        return pdhResult; // выходим, возвращая номер ошибки

// открываем счетчик PDH
    pdhResult = PdhAddCounter(hQuery, szCounterPath, 0, &hCounter);

    if (pdhResult != ERROR_SUCCESS) // если была ошибка, то
        return pdhResult; // выходим, возвращая номер ошибки

 // если дошли до этого места, то ошибки на 100% не было!
    return pdhResult;
}

int GetCPUUsage(HQUERY hQuery, HCOUNTER hCounter, PDH_STATUS &pdhStatus)
// получаем загруженность проца
{
    DWORD       dwType      = 0;

// даем запрос на сборы инфы
    pdhStatus = PdhCollectQueryData(hQuery);

    if (pdhStatus != ERROR_SUCCESS) // если была ошибка, то
        return PDH_ERROR; // выходим, возвращая ошибку

    _PDH_FMT_COUNTERVALUE pfci;
    ZeroMemory(&pfci, sizeof(pfci)); // очищаем структуру pfci

// Получаем инфу о загруженности проца!
    pdhStatus = PdhGetFormattedCounterValue( hCounter, PDH_FMT_DOUBLE, &dwType, &pfci);
   
    if (pdhStatus != ERROR_SUCCESS) // если была ошибка, то
        return PDH_ERROR; // выходим, возвращая ошибку

    return (int)pfci.doubleValue; // возвращаем загруженность проца!
}

void pdh_Uninit(HQUERY hQuery, HCOUNTER hCounter)
// анинициализация
{
    PdhRemoveCounter(hCounter); // удаляем счетчик
    PdhCloseQuery(hQuery); // закрываем запрос
}


правда есть тут одна загадка - все работает более менее корректно, однако первое возвращаемое значение почему-то равно 99% Не понял
Однако иногда аналогичнве вещи наблюдаются и в родном Task managere винды
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #3 : 05-10-2006 20:15 » 

Прочти эту тему https://forum.shelek.ru/index.php/topic,9015.0.html
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #4 : 06-10-2006 04:44 » 

мне кажется проще взять готовые значение у самой ОС
вот эти http://windowssdk.msdn.microsoft.com/en-us/library/ms684847.aspx http://windowssdk.msdn.microsoft.com/en-us/library/ms684894.aspx http://windowssdk.msdn.microsoft.com/en-us/library/ms683210.aspx наборы функций предоставляют искомые данные. там же есть примеры использования + вот это http://windowssdk.msdn.microsoft.com/en-us/library/ms768258.aspx

msdn всё же лучшая база знаний по Win
Записан

Странно всё это....
Mike_I
Участник

ru
Offline Offline
Пол: Мужской
Mike


« Ответ #5 : 06-10-2006 06:54 » 

Привет, народ.

Finch: Прочел то, что ты советовал. Вышел на функцию

GetSystemTimes(LPFILETIME lpIdleTime, LPFILETIME lpKernelTime, LPFILETIME UserTime)

lpIdleTime - A pointer to a FILETIME structure that receives the amount of time that the system has been idle.
lpKernelTime - A pointer to a FILETIME structure that receives the amount of time that the system has spent executing in Kernel mode (including all threads in all processes, on all processors).
lpUserTime - A pointer to a FILETIME structure that receives the amount of time that the system has spent executing in User mode (including all threads in all processes, on all processors).

Первый параметр понятен - время простоя системы.

А вот с двумя другими я не разобрался:
Как понять: "время которое система провела работая в Режиме ядра(2 пар.)/Режиме пользователя(3 пар.)"? Что такое режим Ядра/Пользователя и главное как зная это время вычислить загрузку проца в текущий момент времени, пока это не ясно...  :Улыбаюсь

Осмелюсь предположмить, что сумма значений lpKernelTime и lpUserTime и будет выражать в процентах загрузку проца за 100 наносекундный интервал. Кто что об этом думает?
« Последнее редактирование: 06-10-2006 07:05 от Mike_I » Записан

Nothing fails like success.
Mike_I
Участник

ru
Offline Offline
Пол: Мужской
Mike


« Ответ #6 : 06-10-2006 11:55 » 

Самое обидное, что у меня код содержащий функцию GetSystemTimes() не компилируется  Меня одолевают смутные сомнения.

Причем не компилируется даже если создать совершенно новый проект и вставить туда код примера из MSDN'а: http://www.microsoft.com/rus/msdn/magazine/archive/2003-06/core_api_full.asp

Компилятор всегда выдает ошибку:
DevicedispDlgAuto.cpp(401) : error C3861: 'GetSystemTimes': identifier not found, even with argument-dependent lookup  Здесь была моя ладья...

кто-нибудь знает как это исправить?
« Последнее редактирование: 10-12-2007 17:59 от Алексей1153++ » Записан

Nothing fails like success.
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #7 : 06-10-2006 12:09 » 

вот эти Winbase.h Windows.h хедеры включены?
Записан

Странно всё это....
Mike_I
Участник

ru
Offline Offline
Пол: Мужской
Mike


« Ответ #8 : 06-10-2006 12:13 » 

да
подключал и оба и без них и каждый по отдельности   Да-да
« Последнее редактирование: 06-10-2006 12:18 от Mike_I » Записан

Nothing fails like success.
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #9 : 06-10-2006 12:48 » 

А система у тебя какая? Операционка и среда?

Цитата
Client Requires Windows XP SP1.
...
To compile an application that uses this function, define the _WIN32_WINNT macro as 0x0501 or later.
« Последнее редактирование: 06-10-2006 12:50 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Mike_I
Участник

ru
Offline Offline
Пол: Мужской
Mike


« Ответ #10 : 06-10-2006 12:52 » 

Система: WinXP Prof SP2 + куча всяких исправлений. Среда: VS .net
« Последнее редактирование: 06-10-2006 13:37 от Джон » Записан

Nothing fails like success.
Mike_I
Участник

ru
Offline Offline
Пол: Мужской
Mike


« Ответ #11 : 06-10-2006 13:03 » 

пробовал - эффекта никакого  Улыбаюсь
тока я перед этим делал #undef _WIN32_WINNT а то вылазит Error redifination
Записан

Nothing fails like success.
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #12 : 06-10-2006 13:36 » 

Улыбаюсь) Всё в порядке. Ты только _WIN32_WINNT изменил? Ага  А как же остальные? Те система у тебя всё ещё четвёрка и ИЕ (comctrl-версия) тоже.

Кстати undef не нужен - она же у тебя в самом верху уже есть просто значения измени.

В общем вот так делай:
Код:
#ifndef WINVER				// Lassen Sie die Verwendung von Features spezifisch für Windows 95 und Windows NT 4 oder später zu.
#define WINVER 0x0501 // Ändern Sie den entsprechenden Wert, um auf Windows 98 und mindestens Windows 2000 abzuzielen.
#endif

#ifndef _WIN32_WINNT // Lassen Sie die Verwendung von Features spezifisch für Windows NT 4 oder später zu.
#define _WIN32_WINNT 0x0501 // Ändern Sie den entsprechenden Wert, um auf Windows 98 und mindestens Windows 2000 abzuzielen.
#endif

#ifndef _WIN32_WINDOWS // Lassen Sie die Verwendung von Features spezifisch für Windows 98 oder später zu.
#define _WIN32_WINDOWS 0x0501 // Ändern Sie den entsprechenden Wert, um auf mindestens Windows Me abzuzielen.
#endif

#ifndef _WIN32_IE // Lassen Sie die Verwendung von Features spezifisch für IE 4.0 oder später zu.
#define _WIN32_IE 0x0501 // Ändern Sie den entsprechenden Wert, um auf mindestens IE 5.0 abzuzielen.
#endif

зы Немного подчистил сообщения
« Последнее редактирование: 06-10-2006 13:39 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
alvahtin
Гость
« Ответ #13 : 22-03-2009 13:52 » 

вот что я в свое время нарыл и удачно использовал:
#include <stdio.h>
#include <pdh.h>
#include <conio.h>

Что-то в C++ Builder не получаетцо Жаль. В этом месте:

// создаем путь к счетчику PDH
    pdhResult = PdhMakeCounterPath(&pe, szCounterPath, &dwPathSize, 0);

Выдает код ошибки 0xC0000BBDL, что означает PDH_INVALID_ARGUMENT .
Не понятно, везде говорят, что все у них получается, а тут не работает...

ОС Windows XP.
Записан
alvahtin
Гость
« Ответ #14 : 22-03-2009 15:09 » 

Нашел причину!  Внимание! Говорит и показывает...

1.
Код:
    pe.szMachineName     = 0l;
    pe.szObjectName      = "Processor";
    pe.szInstanceName    = "_Total";
    pe.szParentInstance  = NULL;
    pe.dwInstanceIndex   = 0;
    pe.szCounterName     = "% Processor Time";
Не понимает. Нужно написать по русски:
Код:
    pe.szMachineName     = 0l;
    pe.szObjectName      = "Процессор";
    pe.szInstanceName    = "_Total";
    pe.szParentInstance  = NULL;
    pe.dwInstanceIndex   = (DWORD)-1;
    pe.szCounterName     = "% Загруженности процессора";
а еще лучше:
Код:
    TCHAR szObjectName[256], szCounterName[256], szPath[1024];
    DWORD dwSize;

    pdhStatus = PdhLookupPerfNameByIndex(NULL, 238, szObjectName, &dwSize);//-1
    pdhStatus = PdhLookupPerfNameByIndex(NULL, 6, szCounterName, &dwSize);//-2

    pe.szMachineName     = 0l;
    pe.szObjectName      = szObjectName;
    pe.szInstanceName    = "_Total";
    pe.szParentInstance  = NULL;
    pe.dwInstanceIndex   = (DWORD)-1;
    pe.szCounterName     = szCounterName;
 
   

Тогда все работает как часы  Улыбаюсь
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines