![]() |
Cpu usage EINZELNER PROZESSE ermitteln
ich habe glaube ich so ziemlich alle Threads hier zum Thema CPU Auslastung gelesen, allerdings war dort immer nur die Sprache von der Gesamten momentanen Auslastung. Wie kann ich aber die momentane Auslastung der CPU und die Nutzung des Arbeitsspeichers für jedes einzelne Programm einzeln ermitteln?
Ich habe gehört, dass sowas mit Hilfe von Performancecountern möglich sein soll, aber wie ?? Der Taskmanager muss das ja auch hinbekommen. |
Re: Cpu usage EINZELNER PROZESSE ermitteln
Hier ist die Angabe der Windowsversion von äußerster Wichtigkeit. Also, welche ist es?
|
Re: Cpu usage EINZELNER PROZESSE ermitteln
Windows 2000/XP
Falls das auch noch einen Unterschied macht, dann nur XP ----- |
Re: Cpu usage EINZELNER PROZESSE ermitteln
Es macht keinen ;)
Dann würde ich dich bitten, dir von der ![]() \Win32API\ .\JwaNative.pas .\JwaNtStatus.pas .\JwaWinBase.pas .\JwaWinNT.pas .\JwaWinType.pas Entweder du benutzt direkt einen CVS-Client oder die ![]() Wenn du das hast, bräuchtest du noch etwas Lektüre. Bitte melde dich einmal per PN. |
Re: Cpu usage EINZELNER PROZESSE ermitteln
So. Nun da du im Prinzip alles hast, werde ich mich mal kurz verabschieden um ein kleines Beipiel zu verzapfen, mit dem du dein Ziel erreichen kannst ;)
Nicht Kunst und Wissenschaft allein, Geduld will bei dem Werke seyn. |
Re: Cpu usage EINZELNER PROZESSE ermitteln
Gib mir bitte bis Mittwoch Zeit. Ich muß mich jetzt erstmal anderen Dingen widmen. Ich vergesse es aber nicht. Gruß,
|
Re: Cpu usage EINZELNER PROZESSE ermitteln
Könntest du das dann gleich bitte in die Code-Lib einstellen? Danke.
|
Re: Cpu usage EINZELNER PROZESSE ermitteln
ja kein Problem, so drängt das nicht. Danke :)
|
Re: Cpu usage EINZELNER PROZESSE ermitteln
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
aus diversen Quellen im Netz und der MSDN habe ich nun im Anhang ein kleines Beispielprojekt für dieses Problem. Hinweis: Läuft nur unter NT-Systeme! Kritik und Verbesserungsvorschläge sind erwünscht :???: |
Re: Cpu usage EINZELNER PROZESSE ermitteln
Hi,
ein gutes Beispiel. Es hat aber einen Nachteil: du brauchst ein Handle zu dem entsprechenden Prozess. Es gibt Fälle, wo du das kaum bekommen wirst ;) Ich muß mal gucken, ob man das auch ohne Handle rausbekommt. Muß ich erst noch sehen. @perle: Ich sitze gerade an meinem Beispiel. |
Re: Cpu usage EINZELNER PROZESSE ermitteln
super, bin schon sehr gespannt.
@Catbytes : ich gehe mal davon aus, dass ich das Prozesshandle übergeben muss oder? Wieso bekomme ich dann teilweise negative Werte? Und warum (wenn die Auslastung bei 100% ist) verringert sich die Auslastung wieder auf 0% solange ich das Fenster hin und herschiebe? |
Re: Cpu usage EINZELNER PROZESSE ermitteln
Das ist der Zauber von Application.ProcessMessages() ;)
|
Re: Cpu usage EINZELNER PROZESSE ermitteln
Liste der Anhänge anzeigen (Anzahl: 2)
Die Berechnung anhand der Werte solltest du CatBytes' Beispiel entnehmen. Ansonsten gibt es hier Code, der dir für beliebige Prozesse anhand der PID (also ohne Handle) die entsprechenden Zeiten anzeigt. Einzig die ExitTime wird von meiner Funktion nicht beachtet, da man die wirklich nur mit Handle rausbekommt (und sie für deine Berechnung auch nicht wichtig ist).
Die Units, vom JEDI-Apilib-Projekt brauchst du nach wie vor (es gibt übrigens eine aktualisierte Version von JwaWinType und JwaNative), die du dir und also runterladen solltest. Aus der Funktion CallBackProcess() solltest du das Writeln() entfernen, sobald du es getestet hast. Weil es ja so 1. nur in Konsolenprogrammen funktioniert und 2. nur zum Testen da war. Die wichtige Funktion für dich ist GetProcessTimesByPid()! Alle anderen brauchen dich nicht wirklich zu interessieren. Falls sie es doch tun, kann ich es noch ein wenig erläutern ;) ... Als Test gibt dieses Miniprogramm einfach aus, wann der Prozess mit der hardcodeten PID gestartet wurde. Vorzugsweise sollte die PID natürlich existieren ;) Der Code ist PUBLIC DOMAIN, darf aber natürlich auch unter einer beliebigen OSI-zertifizierten Lizenz benutzt werden - in diesem Falle ist "Copyright (c) 2005 by Mephistopheles" anzugeben. Für die Benutzung der entsprechenden Units gelten die dort angegebenen Lizenzvereinbarungen (üblicherweise MPL für JEDI). Kleines Projekt mit den Funktionen:
Delphi-Quellcode:
BTW: Hatte da einen dummen Fehler drin, den ich jetzt per Debugger gefunden hatte. Ursprüngliche war meine Callback-Funktion als lokale Funktion deklariert. Das ist natürlich tötlich, weil mit jedem Aufruf der Callback sich auch der Stackframe ändert. Logischerweise werden also falsche Pointerwerte vom Stack geholt und es wird versucht auf diese zu schreiben ... *plonk* -> AV! ... naja, die Lehre daraus: Niemals eine Callbackfunktion, die von einer dritten Funktion aufgerufen wird als lokale Funktion deklarieren. Hätte ich eigentlich gleich drauf kommen müssen. Übrigens: deshalb die Kopfstände mit PProcessTimeRecord usw.!
program ProcessTimesNoHandle;
{$APPTYPE CONSOLE} uses Windows, SysUtils, JwaNtStatus, JwaWinType, JwaNative; type TCallBackProcess = function(ps: PSYSTEM_PROCESSES; dwUserData: DWORD): BOOL; stdcall; PProcessTimeRecord = ^TProcessTimeRecord; TProcessTimeRecord = record PID: DWORD; CreationTime, KernelTime, UserTime: LARGE_INTEGER; end; function ListProcesses(Callback: TCallBackProcess; dwUserData: DWORD): Boolean; var Status: NTSTATUS; Buffer: PVOID; TempBuf: PSYSTEM_PROCESSES; BufLen: ULONG; const MinQuerySize = $10000; begin Result := False; BufLen := MinQuerySize; Buffer := RtlAllocateHeap(NtpGetProcessHeap(), HEAP_ZERO_MEMORY, BufLen); if (Assigned(Buffer)) then try Status := NtQuerySystemInformation( SystemProcessesAndThreadsInformation, Buffer, BufLen, nil); while (Status = STATUS_INFO_LENGTH_MISMATCH) do begin // Double the size to allocate BufLen := BufLen * 2; TempBuf := RtlReAllocateHeap(NtpGetProcessHeap(), HEAP_ZERO_MEMORY, Buffer, BufLen); if (not Assigned(TempBuf)) then Exit; // And free "Buffer" inside finally clause // Else assign the TempBuf to Buffer Buffer := TempBuf; // Try to query info again Status := NtQuerySystemInformation( SystemProcessesAndThreadsInformation, Buffer, BufLen, nil); end; // TempBuf used for pointer arithmetics TempBuf := Buffer; if (NT_SUCCESS(Status)) then begin while (True) do begin if (Assigned(Callback)) then if (not CallBack(TempBuf, dwUserData)) then // Exit loop if the callback signalled to do so. Break; // Break if there is no next entry if (TempBuf^.NextEntryDelta = 0) then Break; // Else go to next entry in list TempBuf := PSYSTEM_PROCESSES(DWORD(TempBuf) + TempBuf^.NextEntryDelta); end; Result := True; end; finally if (Assigned(Buffer)) then RtlFreeHeap(NtpGetProcessHeap(), 0, Buffer); end; end; // This MUST NOT be a local function function CallBackProcess(ps: PSYSTEM_PROCESSES; ProcessTimeRecord: PProcessTimeRecord): BOOL; stdcall; begin Result := True; if (Assigned(ps)) then if (ps^.ProcessId = ProcessTimeRecord^.PID) then begin ProcessTimeRecord^.CreationTime := ps^.CreateTime; ProcessTimeRecord^.KernelTime := ps^.KernelTime; ProcessTimeRecord^.UserTime := ps^.UserTime; // FIXME: This is for debugging only. Of course not needed in production code Writeln('PID = ', ps^.ProcessId, ' - parent = ', ps^.InheritedFromProcessId); // Stop going through the list Result := False; end; end; // Instead of only taking the times, it would be easier and more effective to // take all information directly from the SYSTEM_PROCESS structures in the // callback! function GetProcessTimesByPid( PID: DWORD; var lpCreationTime: Windows.FILETIME; var lpKernelTime: Windows.FILETIME; var lpUserTime: Windows.FILETIME ): BOOL; stdcall; var times: TProcessTimeRecord; begin times.PID := PID; // PID to search for // We need to pass a pointer here! Result := ListProcesses(@CallBackProcess, DWORD(@times)); lpCreationTime := Windows.FILETIME(times.CreationTime); lpKernelTime := Windows.FILETIME(times.KernelTime); lpUserTime := Windows.FILETIME(times.UserTime); end; var lpCreationTime, lpKernelTime, lpUserTime: Windows.FILETIME; cst: SYSTEMTIME; begin // Hardcoded PID for testing. This should be called for each PID found if (GetProcessTimesByPid(2588, lpCreationTime, lpKernelTime, lpUserTime)) then begin FileTimeToSystemTime(lpCreationTime, cst); Writeln(Format('Process created: %.4d-%.2d-%.2dT%.2d:%.2d:%.2d.%.3d', [cst.wYear, cst.wMonth, cst.wDay, cst.wHour, cst.wMinute, cst.wSecond, cst.wMilliseconds])); end; Readln; end. PS: Sorry, daß ich dich warten lassen habe. Bin aktuell etwas im Streß (auch außerhalb der DP ;)). PPS: Windows.FILETIME wird explizit benutzt, damit es keinen Konflikt mit dem gleichnamigen (und gleichwertigen) Typen aus der JwaNative.pas (bzw. den zugehörigen Units) beim Kompilieren gibt. PPPS: Im Anhang das Projekt ohne die besagten Units. Die muß man sich bitte selber ![]() |
Re: Cpu usage EINZELNER PROZESSE ermitteln
Leider bekomme ich beim Kompilieren folgende Fehler auch wenn ich die Units einbinde:
[Error] ProcessTimesNoHandle.dpr(32): Undeclared identifier: 'RtlAllocateHeap' [Error] ProcessTimesNoHandle.dpr(32): Undeclared identifier: 'NtpGetProcessHeap' [Error] ProcessTimesNoHandle.dpr(32): Undeclared identifier: 'HEAP_ZERO_MEMORY' [Error] ProcessTimesNoHandle.dpr(44): Undeclared identifier: 'RtlReAllocateHeap' [Error] ProcessTimesNoHandle.dpr(76): Undeclared identifier: 'RtlFreeHeap' |
Re: Cpu usage EINZELNER PROZESSE ermitteln
... die sich mein Lieblings-Mod-Osterhasi aus dem CVS oder als letztes Release (ZIP oder so) runtergeladen hat?
Vertrau mir, ich weiß was ich sage, wenn ich sage: CVS-Version. Du kannst dich gern in der History von den Änderungen seit dem letzten Release (als kompaktes Paket irgendwo auf der Seite verfügbar) überzeugen (u.a. Wachstum um über 700%!). Dann verstehst du warum es nicht geht. |
Re: Cpu usage EINZELNER PROZESSE ermitteln
Habe an den obigen Beitrag die Units noch zusätzlich angehangen, falls es Probleme mit dem CVS gibt. Die Units wurden gestern das letzte Mal aktualisiert eingecheckt. Es ist also taufrisch und noch knusprig-warm.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:13 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz