2009-09-08 6 views
18

Ricerca di funzioni API Win32, codice di esempio C++ o Delphi che indica l'utilizzo della CPU (percentuale e/o tempo totale CPU) di un thread (non il totale per un processo). Ho l'ID del thread.Come ottenere l'utilizzo della cpu per thread su windows (win32)

So che Sysinternals Process Explorer può visualizzare queste informazioni, ma ho bisogno di queste informazioni nel mio programma.

risposta

5

Con l'aiuto della risposta di RRUZ sopra ho finalmente si avvicinò con questo codice per 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

Ma questo ti dà solo il tempo di esecuzione del thread, non la percentuale di utilizzo della CPU. È inoltre possibile ottenere il tempo totale dalle chiamate WMI insieme alla percentuale in una singola query. – skamradt

+0

Penso che sia possibile dedurre la quantità di utilizzo della CPU eseguendo il polling ogni secondo e, se il suo "kernel + usertime" aumenta di 1.0, ciò implica che ha usato il 100% di un core per quel secondo, sì? – rogerdpack

3

Utilizzo di "GetThreadTimes"? Se si misura l'intervallo di tempo tra le chiamate a "GetThreadTimes" e si memorizzano i tempi utente e/o kernel precedenti, si conosce la quantità di tempo che il thread ha avuto dall'ultima volta che si è verificato. Sai anche quanto tempo è trascorso nel frattempo e quindi puoi calcolare quanto tempo di CPU è stato utilizzato. Sarebbe meglio (per ragioni di risoluzione del timer) effettuare questo controllo ogni secondo circa e calcolare il suo utilizzo medio della CPU in quel momento.

20

È necessario utilizzare queste funzioni per ottenere l'utilizzo della cpu per thread ed elaborazione.

GetThreadTimes (recupera informazioni sulla durata del filo specificato.)

GetProcessTimes (recupera temporizzazione informazioni per il processo specificato.)

GetSystemTime (recupera la data e ora del sistema. Il tempo di sistema è espresso in Tempo universale coordinato UTC)

Ecco un ottimo articolo da Dr. Dobb di Win32 Performance Measurement Options

Ciao.

+0

Leggere anche la risposta di lsalamon per notare che GetThreadTimes può essere "meno accurato" – rogerdpack

9

I dati a cui si fa riferimento sono disponibili utilizzando chiamate specifiche WMI. È possibile interrogare Win32_Process per ottenere tutti i tipi di informazioni specifiche del processo e interrogare Win32_PerfFormattedData_PerfProc_Process per ottenere il conteggio dei thread e dato un handle a un thread (cosa credo che si sta cercando) è possibile interrogare Win32_PerfRawData_PerfProc_Thread per ottenere la percentuale di tempo del processore utilizzato.

C'è uno library available for Delphi che fornisce i wrapper per la maggior parte delle query WMI, tuttavia ci vorranno alcuni esperimenti per ottenere la query esatta che si sta cercando. La sintassi di query è molto sql come, ad esempio, sul mio sistema per restituire la percentuale di tempo processore per threadid 8, per id processo 4 è:

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

La maggior parte dei programmi che attualmente le informazioni statistiche sui processi in esecuzione ora utilizzare WMI per richiedere queste informazioni.

6

è importante sapere che in certe situazioni, il tempo di esecuzione di un thread può essere inutile. I tempi di esecuzione di ogni thread vengono aggiornati ogni 15 millisecondi di solito per i sistemi multi-core, quindi se un thread completa l'attività prima di questo momento, il runtime verrà ripristinato. Maggiori dettagli possono essere ottenuti sul link: GetThreadTimes function and I was surprised by the result!
e Why GetThreadTimes is wrong

+3

Apparentemente in Vista + è possibile chiamare QueryThreadCycleTime per una maggiore precisione. http://stackoverflow.com/questions/5532046/c-getthreadtimes-but-with-a-better-resolution La mia ipotesi è che Vista + GetThreadTimes sia anche più preciso, ma TBD. – rogerdpack

0

Here è una semplice query WMI wrapper.Con l'aiuto di esso è possibile chiamare questi dati per ottenere:

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

Inoltre si potrebbe voler esaminare la documentazione Win32_PerfRawData_PerfProc_Thread per vedere quali altre proprietà che è possibile recuperare.