2009-09-08 12 views
18

Buscando funciones de API Win32, C++ o código de ejemplo Delphi que me indica el uso de CPU (porcentaje y/o tiempo total de CPU) de un hilo (no el total de un proceso). Tengo el ID de hilo.Cómo obtener el uso de CPU por hilo en Windows (win32)

Sé que Sysinternals Process Explorer puede mostrar esta información, pero necesito esta información dentro de mi programa.

Respuesta

5

Con la ayuda de la respuesta de RRUZ anterior que finalmente ocurrió con este código para Borland Delphi:

const 
    THREAD_TERMINATE     = $0001; 
    THREAD_SUSPEND_RESUME   = $0002; 
    THREAD_GET_CONTEXT    = $0008; 
    THREAD_SET_CONTEXT    = $0010; 
    THREAD_SET_INFORMATION   = $0020; 
    THREAD_QUERY_INFORMATION   = $0040; 
    THREAD_SET_THREAD_TOKEN   = $0080; 
    THREAD_IMPERSONATE    = $0100; 
    THREAD_DIRECT_IMPERSONATION  = $0200; 
    THREAD_SET_LIMITED_INFORMATION = $0400; 
    THREAD_QUERY_LIMITED_INFORMATION = $0800; 
    THREAD_ALL_ACCESS    = STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or $03FF; 

function OpenThread(dwDesiredAccess: DWord; 
        bInheritHandle: Bool; 
        dwThreadId: DWord): DWord; stdcall; external 'kernel32.dll'; 


procedure TForm1.Button1Click(Sender: TObject); 
var iii:integer; 
    handle:thandle; 
    creationtime,exittime,kerneltime,usertime:filetime; 
begin 
    Handle:=OpenThread(THREAD_SET_INFORMATION or THREAD_QUERY_INFORMATION, False, windows.GetCurrentThreadId); 
    if handle<>0 then 
    begin 
    getthreadtimes(Handle,creationtime,exittime,kerneltime,usertime); 
    label1.caption:='Total time for Thread #'+inttostr(windows.GetCurrentThreadId)+': '+inttostr((int64(kerneltime)+int64(usertime)) div 1000)+' msec'; 
    CloseHandle(Handle); 
    end; 
end; 
+0

Pero esto solo le da el tiempo de ejecución del hilo, no el porcentaje de uso de la CPU. También puede obtener el tiempo total de las llamadas WMI junto con el porcentaje en una sola consulta. – skamradt

+0

Creo que se puede inferir la cantidad de uso de la CPU al sondear cada segundo y, si su "núcleo + tiempo de uso" aumenta en 1,0, eso implica que utilizó el 100% de un núcleo para ese segundo, ¿sí? – rogerdpack

3

¿Estás utilizando "GetThreadTimes"? Si mide el tiempo entre llamadas a "GetThreadTimes" y almacena los tiempos previos de usuario y/o kernel, entonces sabrá cuánto tiempo ha tenido el hilo desde la última vez que lo verificó. También sabe cuánto tiempo ha transcurrido en el tiempo medio y así puede calcular cuánto tiempo de CPU se utilizó. Sería mejor (por razones de resolución de temporizador) hacer esta comprobación cada segundo más o menos y calcular su uso de CPU promedio durante ese segundo.

20

Debe usar estas funciones para obtener el uso de la CPU por subproceso y proceso.

GetThreadTimes (Recupera información de temporización para el hilo especificado.)

GetProcessTimes (Recupera información de temporización para el proceso especificado.)

GetSystemTime (recupera la fecha actual del sistema y el tiempo. El tiempo de sistema se expresa en Tiempo universal coordinado UTC)

aquí un excelente artículo del Dr. Dobb Win32 Performance Measurement Options

Adios.

+0

Lea también la respuesta de lsalamon para saber que GetThreadTimes puede ser "menos que preciso" – rogerdpack

9

Los datos a los que hace referencia están disponibles mediante llamadas específicas WMI. Puede consultar Win32_Process para obtener todo tipo de información específica del proceso, y consultar Win32_PerfFormattedData_PerfProc_Process para obtener el conteo de hilos, y darle un control a un hilo (lo que creo que está buscando) puede consultar Win32_PerfRawData_PerfProc_Thread para obtener el porcentaje del tiempo de procesador utilizado.

Hay un library available for Delphi que proporciona envoltorios para la mayoría de las consultas de WMI, sin embargo, tomará un poco de experimentación para obtener la consulta exacta que busca. La sintaxis de la consulta es muy SQL como, por ejemplo, en mi sistema para devolver el porcentaje de tiempo de procesador para threadid 8, para el identificador de proceso 4 es:

SELECT PercentProcessorTime FROM Win32_PerfRawData_PerfProc_Thread 
    WHERE IdProcess=4 and IdThread=8 

La mayoría de los programas que presentan la información estadística sobre los procesos en ejecución utilizan ahora WMI para consultar esta información.

6

Es importante saber que en ciertas situaciones, el tiempo de ejecución de un hilo puede ser inútil. Los tiempos de ejecución de cada subproceso se actualizan cada 15 milisegundos, por lo general, para sistemas multi-core, por lo que si un subproceso completa su tarea antes de este tiempo, el tiempo de ejecución se restablecerá. Más detalles se pueden obtener en el enlace: GetThreadTimes function and I was surprised by the result!
y Why GetThreadTimes is wrong

+3

Aparentemente en Vista + puedes llamar a QueryThreadCycleTime para mayor precisión. http://stackoverflow.com/questions/5532046/c-getthreadtimes-but-with-a-better-resolution Supongo que con Vista + GetThreadTimes también es más preciso, pero por determinar. – rogerdpack

0

Here es un simple envoltorio consulta WMI.Con ayuda de ella puede llamar a estos datos para obtener:

getWmiQueryResult(L"SELECT PercentProcessorTime FROM Win32_PerfRawData_PerfProc_Thread WHERE IdProcess=4 and IdThread=8", L"PercentProcessorTime "); 

También es posible que desee mirar la documentación Win32_PerfRawData_PerfProc_Thread para ver qué otras propiedades se puede recuperar.

Cuestiones relacionadas