Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Круглый стол
  
Правила КС
>> Настройки

Фильтр вопросов
>> Новые вопросы
отслеживать по
>> Новые ответы

Избранное

Страница вопросов
Поиск по КС


Специальные проекты:
>> К л ю к в а
>> Г о л о в о л о м к и

Вопрос №

Задать вопрос
Off-topic вопросы

Помощь

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
 
 11:52 Geo
 
 
Во Флориде и в Королевстве сейчас  11:56[Войти] | [Зарегистрироваться]
Ответ на вопрос № 37362

05-11-2005 04:25
Здраствуйте.
Подскажите пожалуйста каким образом в Win2K/Xp узнать загруженость процессора конкретным процессом. Например, как в диспечере задач Windows.
GetProcessTimes не советовать, т.к. он возвращает время старта и т.д а мне надо загруженность процессора в процентах.
Заранее спасибо.

[+] Добавить в избранные вопросы

Отслеживать ответы на этот вопрос по RSS

Ответы:


Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице.
Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.

20-12-2007 08:06 | Комментарий к предыдущим ответам
Следует еще поделить на 10000, чтобы получить в миллисекундах.
А зачем? Я же предложил использовать GetSystemTimeAsFileTime вместо GetTickCount (или что там автор использовал), в этом случае никакие лишние преобразования не требуются, просто два вычитания и деление. Нам ведь по сути не интересны единицы измерения времени, мы всё равно хотим получить только отношение "времени работы" к "прошедшему времени".

20-12-2007 04:41
2 DRON

CurrentKernelTime := Int64(lpKernelTime);


Это получится в наносекундах. Следует еще поделить на 10000, чтобы получить в миллисекундах.

12-12-2007 10:01 | Комментарий к предыдущим ответам
А чем не устраивает Pdh.dll?
В данном случае это что "гланды автогеном удалять", никому не нужное усложнение, к тому же я уверен, что Performance Counters будут использовать всё тот же GetProcessTimes.

12-12-2007 09:01
А чем не устраивает Pdh.dll? PdhAddCounter etc?
 NS

12-12-2007 06:49
Вот как следует преобразовывать _FILETIME в миллисекунды:
Проще так:

  CurrentKernelTime := Int64(lpKernelTime);

А вот так делать не стоит:
Result := (CurrentTime - FSaveTime) * 100 / Timer1.Interval;
потому что таймеры очень не стабильны и при сильной загрузке у вас будут совсем не те числа, что вы ожидаете. Лучше сохранять и CurrentTime и реальное время (GetSystemTimeAsFileTime), а в формуле использовать разницу между реальным и запомненным.

12-12-2007 04:48
Вот как следует преобразовывать _FILETIME в миллисекунды:

CurrentKernelTime := (Int64(lpKernelTime.dwHighDateTime shl 32) + lpKernelTime.dwLowDateTime) / 10000;



Итого получаем:

// в глобальных переменных (или как поле формы):
var
  FSaveTime: Extended;

function GetProcessPerf: Double;
var
  lpCreationTime, lpExitTime, lpKernelTime, lpUserTime: _FILETIME;
  CurrentTime: Extended;
begin
  Result := 0;
  GetProcessTimes(GetCurrentProcess, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime);

  // Получаем текущее время как время работы процесса в режиме ядра и в режиме пользователя
  CurrentTime := (Int64(lpKernelTime.dwHighDateTime shl 32) + lpKernelTime.dwLowDateTime) / 10000;
  CurrentTime := CurrentTime + (Int64(lpUserTime.dwHighDateTime shl 32) + lpUserTime.dwLowDateTime) / 10000;

  if (FSaveTime <> 0) then // если первый вызов, то пропускаем
    Result := (CurrentTime - FSaveTime) * 100 / Timer1.Interval;

  FSaveTime := CurrentTime;
end;



Ну и можно усреднить по количеству процессоров, если это необходимо.

11-12-2007 03:47
И у меня.

Я предполагаю, что вот здесь:


Inc(Result, SystemTime.wMilliseconds);
Inc(Result, 1000 * SystemTime.wSecond);



не учитываются минуты, часы и т.д. Ведь процесс может работать значительное время. Это и дает ошибку.

13-07-2007 06:58
У меня ситуация аналогична djdance
Почему может не работать?

28-01-2006 09:45
не заработало - FlashTime дает какие-то числа третьего порядка, CurrFlash скачет около нуля.
чего не так?

07-11-2005 15:28 | Сообщение от автора вопроса
Проверил. Все получилось!
Огромное спасибо.

07-11-2005 15:14
Проверить мне сейчас не на чем, но думаю должен менятся параметр dwNumberOfProcessors получаемый с помощью GetSystemInfo.

07-11-2005 14:23 | Сообщение от автора вопроса
Здраствуйте.
Сделал как вы написали, все нормально показывает, но загруженность процессора у меня отображается примерно в 2 раза больше чем на самом деле.
Тут я задумался и понял :-) ,что у меня включен Hyper-Threading, т.е. 2 процессора и надо делить на 2 (с отключенным Hyper-Threading все соответствовало).
Вопрос: Как узнать включен Hyper-Threading или нет.
Заранее спасибо.

07-11-2005 10:59 | Сообщение от автора вопроса
Спасибо ВСЕМ.

07-11-2005 08:44
Выглядеть всё это будет примерно так:

Возвращаемое суммарное время, потраченное системой на обработку указанного процесса:

function CurrentTime: Integer;
var
  hProcess: THandle;
  lpCreationTime, lpExitTime, lpKernelTime, lpUserTime: TFileTime;
  SystemTime: TSystemTime;

begin
  hProcess := <хендл_процесса>;
  Result  := 0;

  GetProcessTimes(hProcess, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime);

  FileTimeToSystemTime(lpKernelTime, SystemTime);

  Inc(Result, SystemTime.wMilliseconds);
  Inc(Result, 1000 * SystemTime.wSecond);

  FileTimeToSystemTime(lpUserTime, SystemTime);

  Inc(Result, SystemTime.wMilliseconds);
  Inc(Result, 1000 * SystemTime.wSecond);
end;



Вас не интересуют возвращаемые lpCreationTime, lpExitTime, а только lpKernelTime, lpUserTime. Здесь, дубликат инкремента для уменьшения погрешности при переходе ч/з нуль.

Далее, в любом таймере, например TTimer ежесекундно (!) считываем значение CurrentTime и отнимаем его от сохранённого дифференциала на предыдущем этапе и делим на 10 (т.к. % есть значение делённое на 1000 (привязка по оси X к текущему времени), умноженное на 100):

procedure TForm.TimerTimer(Sender: TObject);
var
FlashTime: Integer;

begin
FlashTime := CurrentTime;
CurrFlash := FlashTime - DifTime;
DifTime    := FlashTime;

Caption := Format('CPU usage: %f', [CurrFlash / 10]);
end;



И не забудте определить DifTime при запуске программы: DifTime := CurrentTime;

Кстати еще посмотрите GetProcessIoCounters. На MSDN.


07-11-2005 04:52
GetProcessTimes возвращает чистое время затраченное системой на выполнение процесса (там два времени, но мы их просуммируем). Вызываем GetProcessTimes положим раз в секунду, запоминаем предыдущее время, вычитаем из текущего, делим на секунду, вот вам и загрузка в процентах.

07-11-2005 00:59 | Сообщение от автора вопроса
Если не сложно, то можно написать небольшой пример что-бы понять как это реализовать.
Заранее спасибо.

05-11-2005 07:44
т.к. он возвращает время старта и т.д
Вот на основе этого "и т.д" и происходит расчёт загруженности в процентах.

Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Раз дощечка, два дощечка будет лесенка. Раз словечко, два словечко, будет ЧТО?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.
Тип сообщения:
Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве

    Страница избранных вопросов Круглого стола.
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования