Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   100 % CPU Last durch Thread (https://www.delphipraxis.net/29251-100-cpu-last-durch-thread.html)

lightline 6. Sep 2004 16:51


100 % CPU Last durch Thread
 
Hallo Leute ich habe folgende Aufgabe zu lössen,

Aus meinem Hauptprogramm starte ich einen Thread der Objekte aus einem TreeView abholt eine Serielle Kommunikation durchführt und das Ergebnis wieder zurück schreibt.

Die Bearbeitung der Daten Objekte läuft in ca 20 ms durch und das Zyklisch, hierbei kommt es auf Performance an un das soll auch so schnell wie möglich passieren. Leider bremst dieser Thread meinen Haupthread so stark ab, dass eine normale Bedienung nicht mehr möglich ist. Ich habe es bereits mit ProcessApplication.Messagess, sleep, niedrigere Thread.Priority usw. probiert, leider ohne vernünftigen Erfolg. Die Durchlaufzeit des Thread steigt um den Faktor 100 - 1000 an und die Applikation (Bedienung) wird nicht deutlich besser.

Wie kann ich der Hauptapplikation mehr Rechenzeit zukommen lassen, bzw. wie kann man die Rechenzeit dynamisch aufteilen. ?

:coder2:

supermuckl 6. Sep 2004 17:36

Re: 100 % CPU Last durch Thread
 
eigentlich macht die aufteilung windows
und das über die prioritäten die du vergeben kannst
ansonsten kannst nur du bestimmen durch den code im thread wie stark er das system belastet
wenn du allerdings synchronisations probleme hast ( was ich denke ) dann kann es auch zu diesem problembild kommen.. das der thread und das hauptformular garnicht 100% brauchen sondern nur der hauptthread auf irgendwas "wartet" und dir das deshalb als ausgelastet vor kommt
?!

lightline 6. Sep 2004 20:13

Re: 100 % CPU Last durch Thread
 
Daran habe ich auch schon gedacht bin mir nur nicht ganz sicher wie ich dem ganzen Herr werden kann. ?!

Der Code dazu:


Delphi-Quellcode:
unit UThreadProcess;

interface

uses
  Classes, Main, Windows, UTBCC;

type
  TProzessThread = class(TThread)
  private
    CycleTime: LongInt;
    procedure UpdateMain;
  protected
    procedure Execute; override;
  public
    constructor Create(Tree: TTreeView);
    destructor Destroy;
  end;
Var  ProzessThread : TProzessThread;
      Connect : Bool;
implementation

constructor TProzessThread.Create(Tree: TTreeView);
Begin
  FreeOnTerminate := True;
  inherited Create(True);
end;

destructor TProzessThread.Destroy;
begin
  inherited Destroy;
end;

procedure TProzessThread.UpdateMain;
begin
  begin
    FMain.EZykluszeit.text:= inttostr( GetTickCount - CycleTime)+' ms';
  end;
end;

procedure TProzessThread.Execute;
Var I    : Integer;
    Node : TTreeNode;
begin
  Repeat
  Begin
    for I := 0 to FMain.Treeview1.Items.Count -1 do
    begin
      Node:= FMain.Treeview1.Items[I];
      TBCC(Node.Data).DataExchange(Node);
      Synchronize(UpdateMain);
    end;
    CycleTime:= GetTickCount;
  end;
  until Terminated
end;

end.
[edit=sakura] [delphi]Tags Mfg, sakura[/edit]

dizzy 6. Sep 2004 22:25

Re: 100 % CPU Last durch Thread
 
Ersteinmal herzlich wilkommen in der DP! :dp:

Zweitens: die [ delphi] [ /delphi]-Tags (ohne Leerzeichen) stellen deinen Code im Beitrag formatiert und gehighlighted dar.

Drittens: Das "inherited" sollte im Costruktor immer als erstes kommen, da du sonst u.U. eine Propertiy setzt, die nachher von den Elternklassen wieder überschrieben wird.
Delphi-Quellcode:
constructor TProzessThread.Create(Tree: TTreeView);
Begin
  inherited Create(True);  <--\
                               |  getauscht
  FreeOnTerminate := True; <--/
end;
Und folgendes ist nicht ganz so koscher:
Delphi-Quellcode:
procedure TProzessThread.Execute;
Var I    : Integer;
    Node : TTreeNode;
begin
  Repeat
  Begin
    for I := 0 to FMain.Treeview1.Items.Count -1 do // HIER KÖNNTE ES KNALLEN,
                                                    // DA UNSYNCHRONISIERTER ZUGRIFF AUF FMAIN
    begin
      Node:= FMain.Treeview1.Items[I];             // HIER AUCH
      TBCC(Node.Data).DataExchange(Node);
      Synchronize(UpdateMain);
    end;
    CycleTime:= GetTickCount;
  end;
  until Terminated
end;

end.
Das "begin" und "end" bei einer repeat..until-Schleife kannst du dir übrigends sparen ;).
Die Zugriffe würde ich vermeiden, indem du deiner Threadklasse ein paar Variablen spendierst, und diese mit den nötigen Werten bei der Erzeugung füllst. Somit kannst du nachher schön auf Variablen des Threads zugreifen, ohne solche "Kreuzgriffe" auf's Formular. Ist auf jeden Fall sauberer, auch wenn das jetzige klappt.

Dann solltest du, um das Problem der Auslastung zu verringern nach dem createn des Threads die seine Priority verringern (da hilft die ).
Aber trotzdem wirst du auch bei tpIdle immer 100% Gesamtlast haben, da dein Programm dann ja immer zum Zuge kommt, wenn nichts anderes ansteht. Nur lässt es jetzt jedem anderen Thread/Prozess den Vortritt.
Ein kleiner Vermutstropfen: Der Synchronized-Aufruf, aber es ist ja nur einer, und lässt sich wahrscheinlich auch schwer vermeiden ;).

Ich hoffe, ich konnte etwas helfen :)
Gruss,
dizzy

lightline 7. Sep 2004 14:41

Re: 100 % CPU Last durch Thread
 
danke erst mal für die schnelle Hilfe !!

Habe aber immer noch das Problem, sobald ich den Thread starte eine CPU Auslastung von 100 % ansteht. Sogar wenn ich die Execute Methode völlig entkerne und nur noch Repeat..Until drin lasse. :gruebel:

Besser wird es erst wenn ich den Thread mit Sleep bremse.

Wie ist es eigentlich mit der SleepEx Methode hat da jemand ein Beispiel für mich wie man es verwendet ???

Luckie 7. Sep 2004 15:03

Re: 100 % CPU Last durch Thread
 
Dass sich dein Programm niocht mehr richtig trotz Thread bedienen läßt ist ja irgendwie logisch. In der Execute Methode greifst du ja ständig auf ein Objekt des Hauptformulares zu. Wie wäre es, wenn du statt dessen die benötigten daten an ein Feld der Threadklasse übergibst?

dizzy 7. Sep 2004 15:18

Re: 100 % CPU Last durch Thread
 
Zitat:

Zitat von lightline
Habe aber immer noch das Problem, sobald ich den Thread starte eine CPU Auslastung von 100 % ansteht.

1) Siehe Luckies Beitrag (hatte ich ja auch schon geschrieben)

2) Es geht dir glaube ich nicht darum, dass dein Programm nicht mehr bedienbar ist, sondern dass im Taskmanager 100% CPU-Auslastung steht, gell?
Das wirst du auch mit einem Thread niedrigster Priorität nicht ändern können, da der ja immer dann an die Reihe kommt, wenn nichts weiter anstehet. Die CPU wird immer in Summe zu 100% ausgelastet (wenn ein Programm läuft), und wenn dein Programm das einzige ist, dann bekommt es trotz niedrigem Rang die CPU, weil ja sonst nix ansteht. Sobald sich ein weiteres Programm aktiv dazugesellt, gibt dein Thread Kapazität ab - eben so viel, wie du durch das Setzen der Priotität zulässt - bei tpIdle z.B. wird dein Thread NIE zum Zuge kommen, wenn gleichzeitig ein anderer Thread höherer Priorität läuft. Läuft nichts sonst, bekommst du alles, also 100% (abzüglich OS-Prozesse, die fallen aber nicht in diese Rechnung).

Das Programm so zu drosseln, dass es IMMER < 100% CPU "verbraucht" ist imho nur auf Umwegen und nicht so einfach erreichbar, aber auch meist unsinnig, da du die Priorität ja steuern kannst - und wenn Kapazität verfügbar ist, warum sollte sie dein Thread nicht nutzen? ;)

gruss,
dizzy

lightline 8. Sep 2004 15:38

Re: 100 % CPU Last durch Thread
 
Habe den Thread soweit bereinigt, dass ich ohne Sync und direkten VCL Aufrufen zurande komme ... funktioniert auch prächtig.
Die Sache mit der CPU Auslastung klingt logisch und ich werde den Taskmanager in dieser Beziehung ab jetzt einfach ignorieren :wink:

Gruber_Hans_12345 8. Sep 2004 15:58

Re: 100 % CPU Last durch Thread
 
Zitat:

Zitat von lightline
Habe den Thread soweit bereinigt, dass ich ohne Sync und direkten VCL Aufrufen zurande komme ... funktioniert auch prächtig.
Die Sache mit der CPU Auslastung klingt logisch und ich werde den Taskmanager in dieser Beziehung ab jetzt einfach ignorieren :wink:

Probier einfach ein sleep(0) ind die Schleife einzubauen, dann solltest keine 100% haben und trotzdem alles fast so funktionieren wie bisher !

Gruss
Hans

d7user1 16. Mär 2014 16:36

AW: 100 % CPU Last durch Thread
 
ich habe genau dasselbe problem. mein TThread ruft intern eine Function auf welche ein paar dinge erledigt die auch mal länger dauern können.
innerhalb dieser Function ist eine Repeat-until-Schleife.

ich pausiere das mit einem
Delphi-Quellcode:
while pausiert do LongDelay(25);
.
die prozessorauslastung bleibt aber konstant auf dem vorherigen wert und sinkt nicht auf 0.

ich meine mich zu erinnern dass der wert zuvor immer auf 0 gesunken ist. warum tut er das nicht?

Delphi-Quellcode:
procedure TGenFunctions.LongDelay(Milliseconds: Integer);
var
 Tick: DWord;
 Event: THandle;
begin
 Event := CreateEvent(nil, False, False, nil);
 try
  Tick := GetTickCount + DWord(Milliseconds);
  while (Milliseconds > 0) and (MsgWaitForMultipleObjects(1, Event, False, Milliseconds, QS_ALLINPUT) <>
    WAIT_TIMEOUT) do
   begin
    Application.ProcessMessages;
    if Application.Terminated then
     Exit;
    Milliseconds := Tick - GetTickCount;
   end;
 finally
  CloseHandle(Event);
 end;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:13 Uhr.
Seite 1 von 2  1 2      

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