2009-09-08 7 views
18

Auf der Suche nach Win32-API-Funktionen, C++ oder Delphi-Beispielcode, der mir die CPU-Auslastung (Prozent und/oder gesamte CPU-Zeit) eines Threads (nicht die Summe für ein Prozess). Ich habe die Thread-ID.Wie die CPU-Nutzung pro Thread auf Windows (Win32)

Ich weiß, dass Sysinternals Process Explorer diese Informationen anzeigen kann, aber ich brauche diese Informationen in meinem Programm.

Antwort

5

Mit Hilfe der Antwort des RRUZ oben kam ich endlich mit diesem Code für Borland Delphi up:

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

Aber das gibt Ihnen nur die Zeit, die der Thread ausgegeben wurde, nicht den Prozentsatz der CPU-Auslastung. Sie können die Gesamtzeit aus den WMI-Aufrufen auch zusammen mit dem Prozentsatz in einer einzelnen Abfrage abrufen. – skamradt

+0

Ich denke, dass Sie die Menge der CPU-Nutzung ableiten können, indem Sie jede Sekunde abfragen, und wenn seine "Kernel + Usertime" um 1,0 erhöht, bedeutet das, dass es 100% eines Kerns für diese Sekunde verwendet, ja? – rogerdpack

3

Verwenden von "GetThreadTimes"? Wenn Sie die Zeit zwischen Aufrufen von "GetThreadTimes" messen und die vorherigen Benutzer- und/oder Kernel-Zeiten speichern, wissen Sie, wie viel Zeit der Thread seit der letzten Überprüfung hatte. Sie wissen auch, wie viel Zeit in der Zwischenzeit verstrichen ist und somit können Sie herausfinden, wie viel CPU-Zeit verbraucht wurde. Es wäre am besten (aus Gründen der Zeitauflösung), diese Überprüfung etwa jede Sekunde durchzuführen und die durchschnittliche CPU-Auslastung über diese Sekunde hinweg zu ermitteln.

20

Sie müssen diese Funktionen verwenden, um die CPU-Nutzung pro Thread und Prozess zu erhalten.

GetThreadTimes (Ermittelt Informationen für den angegebenen Thread Timing.)

GetProcessTimes (Ermittelt Informationen für den angegebenen Prozess Timing.)

GetSystemTime (Ermittelt das aktuelle Systemdatum und die Zeit. Die Systemzeit in exprimiert wird Coordinated Universal Time, UTC)

Hier ist ein ausgezeichneter Artikel von Dr. Dobbs Win32 Performance Measurement Options

Wiedersehen.

+0

Lesen Sie auch die Antwort von lsalamon, um festzustellen, dass GetThreadTimes "weniger als genau" sein kann – rogerdpack

9

Die Daten, auf die Sie verweisen, sind unter Verwendung spezifischer -Aufrufe verfügbar. Sie können Win32_Process abfragen, um alle Arten von prozessspezifischen Informationen abzurufen, und Win32_PerfFormattedData_PerfProc_Process abfragen, um die Thread-Anzahl abzurufen, und ein Handle zu einem Thread geben (was ich glaube, dass Sie suchen) können Sie Win32_PerfRawData_PerfProc_Thread abfragen, um den Prozentsatz der Prozessorzeit zu erhalten.

Es gibt eine library available for Delphi, die Wrapper für die meisten WMI-Abfragen bereitstellt. Es bedarf jedoch einiger Experimente, um die genaue Suchanfrage zu erhalten, nach der Sie suchen. Die Abfragesyntax ist sehr sql wie zum Beispiel auf meinem System für threadid 8 den Prozentsatz der Prozessorzeit zurückzukehren, für Prozess-ID 4:

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

Die meisten Programme, die vorliegenden statistischen Informationen über laufende Prozesse jetzt verwenden WMI, um diese Informationen abzufragen.

6

wichtig ist, in bestimmten Situationen kann die Ausführungszeit eines Threads wertlos sein zu wissen, dass. Die Ausführungszeiten jedes Threads werden normalerweise alle 15 Millisekunden für Multicore-Systeme aktualisiert. Wenn also ein Thread seine Aufgabe vor diesem Zeitpunkt abschließt, wird die Laufzeit zurückgesetzt. Weitere Details finden Sie auf den Link erhältlich: GetThreadTimes function and I was surprised by the result!
und Why GetThreadTimes is wrong

+3

Anscheinend in Vista + können Sie QueryThreadCycleTime für mehr Genauigkeit aufrufen. http://stackoverflow.com/questions/5532046/c-getthreadtimes-but-with-a-better-resolution Meine Vermutung ist, dass mit Vista + GetThreadTimes auch genauer, aber TBD ist. – rogerdpack

0

Here eine einfache Abfrage Wrapper WMI ist.Mit Hilfe von es können Sie diese Daten zu erhalten, rufen:

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

Auch möchten Sie vielleicht an der Win32_PerfRawData_PerfProc_Thread Dokumentation schauen, um zu sehen, was andere Eigenschaften, die Sie holen können.