AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Cpu usage EINZELNER PROZESSE ermitteln
Thema durchsuchen
Ansicht
Themen-Optionen

Cpu usage EINZELNER PROZESSE ermitteln

Ein Thema von perle · begonnen am 25. Apr 2005 · letzter Beitrag vom 29. Apr 2005
Antwort Antwort
Seite 2 von 2     12   
perle

Registriert seit: 8. Apr 2004
183 Beiträge
 
Delphi 7 Enterprise
 
#11

Re: Cpu usage EINZELNER PROZESSE ermitteln

  Alt 27. Apr 2005, 12:22
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?
(17:05:33) ( deccer ) duuu keine ahnung vonski?
(17:05:46) ( deccer ) duuuu ober dörticode schreibsorinski?
(17:06:02) ( deccer ) bist doch schlimmor wie uall :F
>> brechi : Livecracking is shice, da sieht man immer die Fehler <<
  Mit Zitat antworten Zitat
Mephistopheles
(Gast)

n/a Beiträge
 
#12

Re: Cpu usage EINZELNER PROZESSE ermitteln

  Alt 27. Apr 2005, 12:36
Das ist der Zauber von Application.ProcessMessages()
  Mit Zitat antworten Zitat
Mephistopheles
(Gast)

n/a Beiträge
 
#13

Re: Cpu usage EINZELNER PROZESSE ermitteln

  Alt 29. Apr 2005, 12:30
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:
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.
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.!

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 hier runterladen. Welche Dateien benötigt werden steht weiter oben.
Angehängte Dateien
Dateityp: zip processtimesnohandle_106.zip (1,6 KB, 51x aufgerufen)
Dateityp: zip processtimesnohandle_units_233.zip (204,2 KB, 50x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#14

Re: Cpu usage EINZELNER PROZESSE ermitteln

  Alt 29. Apr 2005, 12:43
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'
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Mephistopheles
(Gast)

n/a Beiträge
 
#15

Re: Cpu usage EINZELNER PROZESSE ermitteln

  Alt 29. Apr 2005, 12:52
... 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.
  Mit Zitat antworten Zitat
Mephistopheles
(Gast)

n/a Beiträge
 
#16

Re: Cpu usage EINZELNER PROZESSE ermitteln

  Alt 29. Apr 2005, 13:02
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.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:12 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz