![]() |
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; |
AW: 100 % CPU Last durch Thread
Warum innerhalb eines Threads Application.ProcessMessages; ?
|
AW: 100 % CPU Last durch Thread
ohne Application.ProcessMessages in der Sleep-Methode blockt meine anwendung. warum weiß ich nicht. <- quatsch.
habe die procedure nun so geändert dass über eine boolsche variable geprüft wird ob man ProcessMessages braucht oder nicht. wenn der aufruf aus einem thread kommt > nein, sonst > ja. bisher gibt es aber keinen unterschied bezüglich cpu last. |
AW: 100 % CPU Last durch Thread
Zitat:
|
AW: 100 % CPU Last durch Thread
also ein sleep(25) funktioniert im thread. aber im vcl-thread blockt es mir das ganze programm.
|
AW: 100 % CPU Last durch Thread
Wenn du eine Single Core CPU hast und dein Thread viel zu tun hat, spricht aber auch gar nichts dagegen, dass der 100% CPU Last erzeugt. Warum sollte die Aufgabe des Threads denn auch unnötig lange brauchen?
Im Process Explorer kannst du auch schauen welcher Thread überhaupt die Auslastung verursacht. |
AW: 100 % CPU Last durch Thread
Zitat:
|
AW: 100 % CPU Last durch Thread
Wenn im Hauptthread nichts gemacht wird (also keine Messages anstehen),
dann ist diese Schleife ständig nur mit Nachsehen beschäftigt, ob es jetzt was gibt und lastet dann mit Nichts den Kern/Thread zu 100% aus. PS: Selbst ein Sleep(0) kann etwas ausrichten. Jeder Thread bekommt ja bom Sheduler immer paar Millisekunden zum Arbeiten, bis die anderen Threads auch mal etwas Zeit bekommen. Und Sleep(0) gibt die Restzeit sofort ans Windows zurück. |
AW: 100 % CPU Last durch Thread
Wenn ich mir die Execute-Methode da ansehe (von den bösen Zugriffen auf die VCL abgesehen), wundert mich da nichts.
Würde man die Execute-Methode in den Mainthread verlagern und so laufen lassen, wäre die CPU-Last 100%. Warum sollte das also in einem Thread anders sein ? Es ist ein Trugschluß zu glauben, man verlagere seinen Programmcode einfach in einen Thread und *poff*, geht meine CPU-Last auf Null ;) Ein volles Rohr in einer Endlosschleife laufendes Programm belegt eben auch die komplette Zeit die CPU - egal ob nun im Mainthread oder als Nebenthread. Erst, wenn Pausen ins Spiel kommen (zum Beispiel "nur alle 250ms eine Runde durchs TreeView"), geht die Last auch zurück. |
AW: 100 % CPU Last durch Thread
Zitat:
Aber solche Missverständnisse sind vorprogrammiert, wenn man einen alten Thread kapert statt einen eigenen aufzumachen. ;-) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:03 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