Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 696

/ вопрос решён /

Здравствуйте, уважаемые эксперты!Как узнать какая сейчас загрузка ЦП у процессора и отобразить это в gauge?

Аксион Вопрос решён, но можно продолжить его обсуждение в мини-форуме

Вопрос задал: Аксион (статус: 4-ый класс)
Вопрос отправлен: 3 июля 2007, 18:16
Состояние вопроса: решён, ответов: 2.

Ответ #1. Отвечает эксперт: Вадим К

Здравствуйте, ММО!
Как это странно не звучит - прочитать с реестра:)
вот например так, как в приложении.

Приложение:
  1. uses Registry;
  2. .....
  3. procedure TForm1.Timer1Timer(Sender: TObject);
  4. var
  5. reg: TRegistry;
  6. B: array[1..4] of integer;
  7. begin
  8. reg := TRegistry.Create;
  9. reg.RootKey := HKEY_DYN_DATA;
  10. if reg.OpenKey('PerfStatsStatData', false) then
  11. reg.ReadBinaryData('KERNELCPUusage', b, 4);
  12. reg.CloseKey;
  13. Gauge1.Progress := b[1];
  14. end;


Ответ отправил: Вадим К (статус: Академик)
Время отправки: 3 июля 2007, 18:39
Оценка за ответ: 5

Ответ #2. Отвечает эксперт: Dron

Здравствуйте, ММО!
В приложении код, получающий информацию не только о загрузке процессора, но и о самом процессоре. Ненужное, конечно, можно (и даже желательно) удалить. Для работы на Form1 должен быть размещён Label1. А в любом месте программы (например, при нажатии на кнопку) нужно вызвать функцию: GetCPUUsage; Вначале появится окно с информацией о процессоре (чтобы убрать это окно нужно удалить строку ShowMessage(...) в процедуре), а затем в Label1 будет показываться уровень загрузки процессора (в процентах). Вызвать функцию достаточно один раз - она сама вызывает себя снова каждую секунду. Ассоциировать счётчик с TGauge можно так:
Form1.Gauge1.Progress:=Round(dbIdleTime);
Это следует написать вместо строки Form1.Label1.Caption := FormatFloat('CPU Usage: 0.0 %',dbIdleTime);

Приложение:
  1. const
  2. SystemBasicInformation = 0;
  3. SystemPerformanceInformation = 2;
  4. SystemTimeInformation = 3;
  5.  
  6. type
  7. TPDWord = ^DWORD;
  8.  
  9. TSystem_Basic_Information = packed record
  10. dwUnknown1: DWORD;
  11. uKeMaximumIncrement: ULONG;
  12. uPageSize: ULONG;
  13. uMmNumberOfPhysicalPages: ULONG;
  14. uMmLowestPhysicalPage: ULONG;
  15. uMmHighestPhysicalPage: ULONG;
  16. uAllocationGranularity: ULONG;
  17. pLowestUserAddress: Pointer;
  18. pMmHighestUserAddress: Pointer;
  19. uKeActiveProcessors: ULONG;
  20. bKeNumberProcessors: byte;
  21. bUnknown2: byte;
  22. wUnknown3: word;
  23. end;
  24.  
  25. type
  26. TSystem_Performance_Information = packed record
  27. liIdleTime: LARGE_INTEGER; {LARGE_INTEGER}
  28. dwSpare: array[0..75] of DWORD;
  29. end;
  30.  
  31. type
  32. TSystem_Time_Information = packed record
  33. liKeBootTime: LARGE_INTEGER;
  34. liKeSystemTime: LARGE_INTEGER;
  35. liExpTimeZoneBias: LARGE_INTEGER;
  36. uCurrentTimeZoneId: ULONG;
  37. dwReserved: DWORD;
  38. end;
  39.  
  40. var
  41. NtQuerySystemInformation: function(infoClass: DWORD;
  42. buffer: Pointer;
  43. bufSize: DWORD;
  44. returnSize: TPDword): DWORD; stdcall = nil;
  45.  
  46.  
  47. liOldIdleTime: LARGE_INTEGER = ();
  48. liOldSystemTime: LARGE_INTEGER = ();
  49.  
  50. function Li2Double(x: LARGE_INTEGER): Double;
  51. begin
  52. Result := x.HighPart * 4.294967296E9 + x.LowPart
  53. end;
  54.  
  55. procedure GetCPUUsage;
  56. var
  57. SysBaseInfo: TSystem_Basic_Information;
  58. SysPerfInfo: TSystem_Performance_Information;
  59. SysTimeInfo: TSystem_Time_Information;
  60. status: Longint; {long}
  61. dbSystemTime: Double;
  62. dbIdleTime: Double;
  63.  
  64. bLoopAborted : boolean;
  65.  
  66. begin
  67. if @NtQuerySystemInformation = nil then
  68. NtQuerySystemInformation := GetProcAddress(GetModuleHandle('ntdll.dll'),
  69. 'NtQuerySystemInformation');
  70.  
  71. // get number of processors in the system
  72.  
  73. status := NtQuerySystemInformation(SystemBasicInformation, @SysBaseInfo, SizeOf(SysBaseInfo), nil);
  74. if status <> 0 then Exit;
  75.  
  76. // Show some information
  77. with SysBaseInfo do
  78. begin
  79. ShowMessage(
  80. Format('uKeMaximumIncrement: %d'#13'uPageSize: %d'#13+
  81. 'uMmNumberOfPhysicalPages: %d'+#13+'uMmLowestPhysicalPage: %d'+#13+
  82. 'uMmHighestPhysicalPage: %d'+#13+'uAllocationGranularity: %d'#13+
  83. 'uKeActiveProcessors: %d'#13'bKeNumberProcessors: %d',
  84. [uKeMaximumIncrement, uPageSize, uMmNumberOfPhysicalPages,
  85. uMmLowestPhysicalPage, uMmHighestPhysicalPage, uAllocationGranularity,
  86. uKeActiveProcessors, bKeNumberProcessors]));
  87. end;
  88.  
  89.  
  90. bLoopAborted := False;
  91.  
  92. while not bLoopAborted do
  93. begin
  94.  
  95. // get new system time
  96. status := NtQuerySystemInformation(SystemTimeInformation, @SysTimeInfo, SizeOf(SysTimeInfo), 0);
  97. if status <> 0 then Exit;
  98.  
  99. // get new CPU's idle time
  100. status := NtQuerySystemInformation(SystemPerformanceInformation, @SysPerfInfo, SizeOf(SysPerfInfo), nil);
  101. if status <> 0 then Exit;
  102.  
  103. // if it's a first call - skip it
  104. if (liOldIdleTime.QuadPart <> 0) then
  105. begin
  106.  
  107. // CurrentValue = NewValue - OldValue
  108. dbIdleTime := Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime);
  109. dbSystemTime := Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);
  110.  
  111. // CurrentCpuIdle = IdleTime / SystemTime
  112. dbIdleTime := dbIdleTime / dbSystemTime;
  113.  
  114. // CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors
  115. dbIdleTime := 100.0 - dbIdleTime * 100.0 / SysBaseInfo.bKeNumberProcessors + 0.5;
  116.  
  117. // Show Percentage
  118. Form1.Label1.Caption := FormatFloat('CPU Usage: 0.0 %',dbIdleTime);
  119.  
  120. Application.ProcessMessages;
  121.  
  122. // Abort if user pressed ESC or Application is terminated
  123. bLoopAborted := (GetKeyState(VK_ESCAPE) and 128 = 128) or Application.Terminated;
  124.  
  125. end;
  126.  
  127. // store new CPU's idle and system time
  128. liOldIdleTime := SysPerfInfo.liIdleTime;
  129. liOldSystemTime := SysTimeInfo.liKeSystemTime;
  130.  
  131. // wait one second
  132. Sleep(1000);
  133. end;
  134. end;


Ответ отправил: Dron (статус: Студент)
Время отправки: 3 июля 2007, 19:34
Оценка за ответ: 5


Мини-форум вопроса

Всего сообщений: 29; последнее сообщение — 4 июля 2007, 20:20; участников в обсуждении: 3.

Страницы: [1] [2] [Следующая »]

Dron

Dron (статус: Студент), 3 июля 2007, 18:54 [#1]:

Вадим К: а если требуется постоянно отображать загрузку процессора, а не единовременно? Чтение из реестра - не лучший вариант.
Ведь есть способ узнать загрузку "системным" способом...
С уважением.
Вадим К

Вадим К (статус: Академик), 3 июля 2007, 19:18 [#2]:

Вы хорошо посмотрели пример? если присмотритесь внимательно и попробуете найти эту ветку в реесте, то её там нет! а код работает. Почему так? Просто в реестре есть ветка, которая хранит всякую подобную информацию. и находиться она в оперативной памяти. Поэтому чтение с неё ничуть не быстрее вызова высокоуровневых функций. Можно конечно вызывать другие, но они либо читают отсюдова же, либо копают глубже, но толку то?

Повторюсь. Эта ветка реестра виртуальна. на диск она не сохраняется.

>>Ведь есть способ узнать загрузку "системным" способом...
А почему не привели? или боитесь?
Галочка "подтверждения прочтения" - вселенское зло.
Dron

Dron (статус: Студент), 3 июля 2007, 19:37 [#3]:

Если честно, про виртуальный реестр не знал :-) Хорошо придумано. Только вот объект тогда имеет смысл создать только один раз, а не создавать и удалять каждый раз при срабатывании таймера.

> А почему не привели? или боитесь?
Чего же бояться-то? :-) Просто начал искать код после ответа на Ваше сообщение...
С уважением.
Вадим К

Вадим К (статус: Академик), 3 июля 2007, 19:44 [#4]:

Ну если на объекте начать экономить, тогда уже наверно нужно на апи перейти. там уже реально экономия.
Галочка "подтверждения прочтения" - вселенское зло.
Аксион

Аксион (статус: 4-ый класс), 4 июля 2007, 13:56 [#5]:

вадим к твой метод не работает он всегда показывает 100% когда диспетчер задач 2%
Аксион

Аксион (статус: 4-ый класс), 4 июля 2007, 13:58 [#6]:

да и мне надо именно Цп а не cpu
Аксион

Аксион (статус: 4-ый класс), 4 июля 2007, 14:01 [#7]:

dron а твой метод работает и показывает именно цп
Аксион

Аксион (статус: 4-ый класс), 4 июля 2007, 14:02 [#8]:

но я обоим ставлю 5 :)
Dron

Dron (статус: Студент), 4 июля 2007, 14:20 [#9]:

А у меня наоборот - всё время показывает 0%... Вадим, может ошибка в коде где?
С уважением.
Вадим К

Вадим К (статус: Академик), 4 июля 2007, 14:38 [#10]:

А чем Цп от cpu отличается???
А во вторых с учётом паники майкрософт, что злые пользователи реестр почистят доступ к этому ключу прикрыли. Жаль. Работало раньше просто наура
Галочка "подтверждения прочтения" - вселенское зло.
Вадим К

Вадим К (статус: Академик), 4 июля 2007, 14:39 [#11]:

а выдавать может что угодно, так как в массив ничего не пишеться...
Галочка "подтверждения прочтения" - вселенское зло.
Аксион

Аксион (статус: 4-ый класс), 4 июля 2007, 14:46 [#12]:

dron кстати от метода который выомп сильно виснет!
Аксион

Аксион (статус: 4-ый класс), 4 июля 2007, 14:49 [#13]:

dron от метода который вы порекомендовали комп сильно виснет
Dron

Dron (статус: Студент), 4 июля 2007, 14:57 [#14]:

Вадим К: тогда, наверное, стоит проверять предлагаемое решение перед отправкой?

MMO: Хм. У меня ничего не вешает. Может вы интервал обновления поставили слишком маленький или слишком большой? Если слишком большой, то да, будут тормоза, потому что там используется Sleep. В этом случае нужно просто выкинуть всё ненужное и оставить лишь процедуру вывода, которую вызывать откуда-то из другого места (по таймеру например).
С уважением.
Аксион

Аксион (статус: 4-ый класс), 4 июля 2007, 15:00 [#15]:

а я всегда ставлю 5
Вадим К

Вадим К (статус: Академик), 4 июля 2007, 15:01 [#16]:

Дело в том, что у меня то работает. просто у меня винда с отключеными разными "в помощь простому юзеру".
То ММО: юзаем потоки! Sleep в основном потоке - зло
Галочка "подтверждения прочтения" - вселенское зло.
Аксион

Аксион (статус: 4-ый класс), 4 июля 2007, 15:03 [#17]:

dron у меня прога показывает название, версия, путь, язык ОС; версия DOS; тип, тип питания, скорость, имя компьютера; CPU, Фаил подкачки, Виртуальная память; Название видеокарты, название драйверов, разрешение экрана, глубина цвета.
Умеет менять разрешение экрана (!некоторых разрешений даже нет в параметрах экрана)и всё это обновляется каждую секунду может быть по этому после вызова ещё и вацедуры он виснет?
Аксион

Аксион (статус: 4-ый класс), 4 июля 2007, 15:04 [#18]:

и вашей а не и вацедуры -опечатался :)
Dron

Dron (статус: Студент), 4 июля 2007, 15:04 [#19]:

> а я всегда ставлю 5
Логичный вопрос: зачем? Остальные оценки для кого придумали? Нужно проверять предлагаемые решения, а только затем ставить оценки...
С уважением.
Аксион

Аксион (статус: 4-ый класс), 4 июля 2007, 15:05 [#20]:

процедурыабыл :)

Страницы: [1] [2] [Следующая »]

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:26
Выполнено за 0.02 сек.