Hi ,
aus den ganzen Infos und dem Code-Beispiel von (m.fuchs) habe ich jetzt mal ein Demo gebaut.
Ist ja eingentlich ganz einfach , wenn man erst mal eine Schubs bekommt .
Habe für das einlesen von '/proc/stat' mal ein Memo genommen , da sieht man alles schön im Klartext.
Später nimmt man dann halt eine Stringlist im verborgenen.
In Button1.click wird das Memo ausgewertet .
Und ein Timer triggert den Button in gewissen Abständen.
Code: Alles auswählen
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
ExtCtrls ;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Memo2: TMemo;
Timer1: TTimer; // Interval auf 250ms eingestellt
procedure Button1Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
public
end;
var
Form1: TForm1;
str1,str2:string;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
var prozesor_count,i,p:integer;
z,w1,w2:string;
array1,array2:tstringarray;
total_1,work_1,total_2,work_2:integer;
work_over_period,total_over_period:integer;
cpu_last_proz:double;
begin
// Timer während der Auswertung abschalten
// damit einem nich ein neuer Timeraufruf dazwischenfunkt
timer1.Enabled:=false;
// Hier wird jetzt mal ein Memo genommen , um alles visuell zu betrachten
// später dann eine Stringlist benutzen
memo2.Lines.BeginUpdate;
memo2.Lines.LoadFromFile('/proc/stat');
memo2.Lines.EndUpdate;
// Anzahl der verfügbaren Prozessorkerne ermitteln , weil man die Information
// auch im '/proc/stat' geliefert bekommt .
// Könnte man in eine separate Funktion auslagern , da ja die eigentliche
// Aufgabe die Berechnung der Prozessor-Last ist
prozesor_count:=0;
for i:=0 to memo2.Lines.Count-1 do
begin
z:=uppercase(memo2.Lines[i]);
if pos('CPU',z)>0 then inc(prozesor_count);
end;
// Einen weniger , weil in der ersten Zeile von '/proc/stat' die
// Gesamt-Prozessor-Infos stehen
dec(prozesor_count);
// Gesamtprozessorlast berechnen
if str1='' // beim allerersten Timerdurchlauf
then str1:=memo2.Lines[0]
else // bei allen weiteren Timerdurchläufen
begin
memo1.Clear;
memo1.Lines.Add('Anzahl Prozessorkerne = '+inttostr(prozesor_count));
str2:=memo2.Lines[0];
// Für interne Stringzerlegung kopieren
w1:=str1;
w2:=str2;
// Teilstring , Cpu-Text löschen
// und Vorlauf-Leerzeichen beseitigen
delete(w1,1,pos(' ',w1));
w1:=trimleft(w1);
delete(w2,1,pos(' ',w2));
w2:=trimleft(w2);
// str1 und str2 in arrays zerlegen
array1:=w1.split(' ');
array2:=w2.split(' ');
// Summen berechnen
// Vorgehensweise ist unter
// https://stackoverflow.com/questions/3017162/how-to-get-total-cpu-usage-in-linux-using-c
// beschrieben
// total_1 = (sum of all values) array1
total_1:=0;
for i:=0 to 9 do
total_1:=total_1+strtoint(array1[i]);
// work_1 = (sum of user,nice,system = the first 3 values) array1
work_1:=0;
for i:=0 to 2 do
work_1:=work_1+strtoint(array1[i]);
// total_2 = (sum of all values) array2
total_2:=0;
for i:=0 to 9 do
total_2:=total_2+strtoint(array2[i]);
// work_1 = (sum of user,nice,system = the first 3 values) array2
work_2:=0;
for i:=0 to 2 do
work_2:=work_2+strtoint(array2[i]);
// Verrechnen
// So the %cpu usage over this period is:
work_over_period:= work_2 - work_1;
total_over_period:= total_2 - total_1;
// %cpu = work_over_period / total_over_period * 100
cpu_last_proz:=work_over_period / total_over_period * 100;
memo1.Lines.Add('Gesamt-Prozessorlast = '+FormatFloat('000.0',cpu_last_proz)+'[%]');
str1:=str2;
end;
// Timer wieder scharf schalten
timer1.Enabled:=true;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
button1.click;
end;
initialization
str1:='';
str2:='';
end.
Als nächstes bau ich mir noch ne Unit in der dann OS-abhängig , die Linux- oder Windows-Funktion kompiliert wird.
Alles super , ich danke euch .
Linux-Demo im Anhang.
Gruß
Frank