Экспертная система 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 (статус: Студент), 4 июля 2007, 15:06 [#21]:

Sleep нужно убрать и обновление делать вручную - тогда висеть не будет.
С уважением.
Аксион

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

попробую а всем 5 ставлю за то что откликнулись вас экспертов всего около 80 а помогают около 5 чем занимаются остальные?
Аксион

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

dron если убрать sleep то программа выдаёт ошибку а есле снизить время то вообще показывает фигню
Вадим К

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

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

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

а как их юзать О_о
Аксион

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

блин windows переустанавливать надо безконца сининий экран смерти и клава глючит - вы в этом уже убедились
Вадим К

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

Это другой вопрос. Гуглите на тему TThread. А вот если уж ничего не будет - наваяем
Галочка "подтверждения прочтения" - вселенское зло.
Аксион

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

уже на яндексе
Аксион

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

Вадим К можно одну прозьбу, переработай код dronа чтобы комп не вис и не было ошибок и опубликуй здесь - буду очень признателен

31 января 2011, 19:27: Статус вопроса изменён на решённый (изменил модератор Ерёмин А.А.): Автоматическая обработка (2 и более ответов с оценкой 5)

Страницы: [« Предыдущая] [1] [2]

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

Версия движка: 2.6+ (26.01.2011)
Текущее время: 26 апреля 2026, 05:13
Выполнено за 0.03 сек.