![]() |
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: |
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 ?! |
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:
[edit=sakura] [delphi]Tags Mfg, sakura[/edit]
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. |
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:
Und folgendes ist nicht ganz so koscher:
constructor TProzessThread.Create(Tree: TTreeView);
Begin inherited Create(True); <--\ | getauscht FreeOnTerminate := True; <--/ end;
Delphi-Quellcode:
Das "begin" und "end" bei einer repeat..until-Schleife kannst du dir übrigends sparen ;).
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. 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 |
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 ??? |
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?
|
Re: 100 % CPU Last durch Thread
Zitat:
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 |
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: |
Re: 100 % CPU Last durch Thread
Zitat:
Gruss Hans |
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:18 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