Ir al contenido



Foto

Saber Consumo cpu de proceso y total


  • Por favor identifícate para responder
3 respuestas en este tema

#1 monchito_elroro

monchito_elroro

    Advanced Member

  • Miembros
  • PipPipPip
  • 249 mensajes

Escrito 09 noviembre 2017 - 12:48

buenas amigos a los tiempos, saludos con todos.

disculpen la molestia estoy tratando de crear un administrador de tareas, de momento me va bien pero estoy estancado en la parte para saber cuanto consumo de cpu realiza cada proceso y también obtener el consumo total de cpu.

 

si me pudieran ayudar se los agradecería muchísimo, saludos y un abrazo gigante :)


  • 0

#2 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.696 mensajes
  • LocationMadrid - España

Escrito 18 noviembre 2017 - 09:55

El problema debería ser mas sencillo de lo que es pero Microsoft gusta de no facilitar las cosas con la intuición.

 

Para medir el consumo de la CPU debemos medir el tiempo que dedica a una tarea no activa, calcular el porcentaje y restarlo de 100, otra forma es usar la PDH_API para poner en marcha un contador que nos dará una medida puntual del consumo de la CPU.  Esta medida es puntual, por lo que si queremos tener una medición por segundo, deberemos hacer varias medidas y hacer una media en ese intervalo. El siguiente código nos realiza una medida puntual


delphi
  1. var
  2. hQuery: PDH_HQUERY;
  3. cpuTotal: PDH_HCOUNTER;
  4.  
  5.  
  6. //Para consumo de CPU
  7. procedure InitSampleCPU;
  8. begin
  9. PdhOpenQuery(nil, 0, hQuery);
  10. PdhAddEnglishCounterA(hQuery, '\Processor(_Total)\% Processor Time', 0, cpuTotal);
  11. end;
  12.  
  13. function GetSampleCPUValue: double;
  14. var
  15. counterVal: PDH_FMT_COUNTERVALUE;
  16. begin
  17. Status:= PdhCollectQueryData(hQuery);
  18. Status:= PdhGetFormattedCounterValue(cpuTotal, PDH_FMT_DOUBLE, nil, @counterVal);
  19. Result:= counterVal.doubleValue;
  20. end;

Para medir el consumo de un proceso, es mejor medir el consumo gastado en modo Kernel, sumarlo al consumo de modo usuario y dividirlo por el tiempo de CPU realmente transcurrido entre dos mediciones, entre el número de procesadores y multiplicarlo por 100. De esa forma obtenemos el porcentaje de tiempo de CPU usado por un proceso en un intervalo de tiempo dado (entre dos medidas)

He definido la estructura TIME_PROC_VALUE para guardar y refrescar los tiempos obtenidos de la medida anterior, de esta forma conseguimos un valor medio entre las dos medidas. Si queremos monitorizar más de un proceso, debemos declarar una variable del tipo TIME_PROC_VALUE para cada uno de ellos, inicializarla y usarla como parámetro para realizar la medida con la función implementada más abajo: GetProcessValue


delphi
  1. type
  2. TIME_PROC_VALUE = record
  3. PID: DWORD;
  4. lastCPU: ULARGE_INTEGER;
  5. lastUTime: ULARGE_INTEGER;
  6. lastKTime: ULARGE_INTEGER;
  7. end;
  8. PTIME_PROC_VALUE = ^TIME_PROC_VALUE;
  9.  
  10. var
  11. numProcessors: integer;
  12. TV: TIME_PROC_VALUE;
  13.  
  14.  
  15. procedure InitFromPID(PID: DWORD; var TimeValue: TIME_PROC_VALUE);
  16. var
  17. sysInfo: SYSTEM_INFO;
  18. time: FILETIME;
  19. hProcess: THANDLE;
  20. begin
  21. GetSystemInfo(sysInfo);
  22. numProcessors:= sysInfo.dwNumberOfProcessors;
  23.  
  24. GetSystemTimeAsFileTime(FILETIME(TimeValue.lastCPU));
  25. hProcess:= OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, PID);
  26. GetProcessTimes(hProcess, time, time, FILETIME(TimeValue.lastKTime), FILETIME(TimeValue.lastUTime));
  27. CloseHandle(hProcess);
  28. TimeValue.PID:= PID;
  29. end;
  30.  
  31. function GetProcessValue(var TimeValue: TIME_PROC_VALUE): double;
  32. var
  33. time: FILETIME;
  34. now, kernel, user: ULARGE_INTEGER;
  35. hProcess: THANDLE;
  36. begin
  37. Result:= 0;
  38. hProcess:= OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, TimeValue.PID);
  39. if hProcess <> 0 then
  40. begin
  41. GetSystemTimeAsFileTime(FILETIME(now));
  42. GetProcessTimes(hProcess, time, time, FILETIME(kernel), FILETIME(user));
  43. Result:= (kernel.QuadPart - TimeValue.lastKTime.QuadPart) + (user.QuadPart - TimeValue.lastUTime.QuadPart);
  44. Result:= 100*((Result / (now.QuadPart - TimeValue.lastCPU.QuadPart)) / numProcessors);
  45. TimeValue.lastCPU:= now;
  46. TimeValue.lastKTime:= kernel;
  47. TimeValue.lastUTime:= user;
  48. CloseHandle(hProcess);
  49. end;
  50. end;

Subo un pequeño programita como ejemplo. En él no me he molestado en sacar el consumo de la CPU como media en un intervalo, obtengo sólo consumos puntuales, Una idea que dejo en el aire es tomar 10 medidas durante un segundo y realizar la media que se mostrará cada segundo

 

El código está probado en delphi 7 pero no debe haber dificultades para portarlo a Berlin o Lazarus, observar que uso la versión AnsiChar de la API PdhAddEnglishCounter (PdhAddEnglishCounterA) el que lo prefiera puede usar la versión UNICODE (PdhAddEnglishCounterW)

 

Saludos.

Archivos adjuntos


  • 1

#3 monchito_elroro

monchito_elroro

    Advanced Member

  • Miembros
  • PipPipPip
  • 249 mensajes

Escrito 18 noviembre 2017 - 08:25

Buenas amigo "Escafranda" le agradezco por ayudarme con este problema, voy a tratar de implementarlo en el proyecto que estoy realizando y lo subiré para todo aquel que le pueda servir.

 

también sino fuera mucha molestía que signica "consumos puntuales" es el consumo de cpu en porcentaje ?


  • 0

#4 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.696 mensajes
  • LocationMadrid - España

Escrito 19 noviembre 2017 - 10:55

Los consumos dados son en porcentaje del total del tiempo de uso de la CPU

 

Saludos.


  • 0