![]() |
Threads Suspend -> Resume ... wo gehts weiter?
Hallo!
Ich beschäftige mich derzeit ein bisserl mit Threads und hab' da ein kleines Verständnisproblem: Wenn ich einen Thread starte, führt diese die Prozedur 'Execute' aus. Sobald der Thread mit seiner Arbeit fertig ist (... die Execute-Prozedur durchlaufen ist), setze ich den Thread in den Suspended-State (Er pausiert also). Wenn ich nun den Thread mit Resume wieder zum Leben erwecke, wo fährt der Thread mit seiner arbeit fort? Startet er erneut die Execute-Prozedur oder arbeitet er einfach die nächste Zeile ab, wo ich ihn zuvor pausiert habe? Greetings Gerald |
Re: Threads Suspend -> Resume ... wo gehts weiter?
Er macht genau da weiter, wo du ihn suspended hast...
aber das lässt sich leicht hiermit herausfinden:
Code:
greetz
procedure TMeinThread.execute;
var i: integer; begin while not terminated do begin form1.Memo1.Lines.Add(inttostr(i)); i := i + 1; sleep(500); end; end; -FastJack2 |
Re: Threads Suspend -> Resume ... wo gehts weiter?
Zitat:
Legst du den Thread von außen schlafen, kann man nicht sagen, wo er angehalten wird. Es kann zB mitten innerhalb einer Anweisung (auf HLL-Ebene) geschehen ... zB während ein Parameter bereits auf dem Stack liegt, der nächste aber noch nicht. Man kann es also nicht voraussagen, kann aber den Threadkontext holen und auch setzen (Rechte vorausgesetzt), wo unter anderen die aktuelle Adresse des EIP (Instruction Pointer) drinsteht. |
Re: Threads Suspend -> Resume ... wo gehts weiter?
ich habe das so verstanden dass er den thread wieder starten will nachdem die Execute-procedure abgearbeitet und schon wieder verlassen worden ist.
ich weiss allerdings gerade nicht ob man einen Thread, der mit der Execute-Methode fertig ist (und bei dem FreeOnTerminate auf False steht) so einfach mit Resume wieder von vorne starten kann (ich denke mal das wird nämlich der Threadersteller vorhaben). edit: für dieses Vorhaben wäre auch das Event OnTerminate ganz nützlich. |
Re: Threads Suspend -> Resume ... wo gehts weiter?
Wenn ich mal davon ausgehen darf, das es hier um eine beendete Execute-Prozedur geht, dann will ich hiermit dringlichst davon abraten, diese wieder per "Execute"-Aufruf zu starten. Dann verhält sie sich nämlich wie eine Prozedur und der ganze Vorteil eines Threads ist weg. Ich für meinen Teil mache das dann immer so:
Delphi-Quellcode:
procedure TThread.Execute();
begin while not Self.Suspended do begin //Machwas; end; end; |
Re: Threads Suspend -> Resume ... wo gehts weiter?
Meiner Meinung nach macht ein Thread nur Sinn, wenn Du eine wiederholende Arbeit damit ausführst, sonnst kann man nämlich eine normales Objekt mit Methode für die Verarbeitung verwenden. Ich gehe mal davon aus dass Du auf einer Maschine mit nur einem Prozessor arbeitets, also eigentlich sowieso alles sequentiell abläuft.
Dann sollte eine Execute Methode so aussehen:
Delphi-Quellcode:
Von der logik her wird das System die While .. do Schleife solange durchlaufen, bis die Bedingung termineted auf true gesetzt wird.
procedure TMeinThread.execute;
var i: integer; begin while not terminated do begin form1.Memo1.Lines.Add(inttostr(i)); i := i + 1; sleep(500); end; end; Wenn nun von aussen die Methode suspend aufgerufen wird, hält der Thread genau an der Zeile an, wo er gerade war. Im obigen Fall wird das mit 99.99% Wahrscheinlichkeit bei der Zeile sleep(500) der Fall sein. Falls Du an einer bestimmten stelle immer anhalten möchtest kannst Du Dir einfach folgendes Hilfskonstrukt in die execute Methode einbauen:
Delphi-Quellcode:
Bei der Anweisung Terminate musst Du ebenfalls beachten, dass der Thread nicht sofort beendet wird, sondern lediglich das Property Termineted auf True gesetz wird. Somit läuft die Execute Methode nochmal bis zum Ende durch. Könnte unerwünschte Nebeneffekte haben.
[b]procedure TMeinThread.SetSuspend;
begin SuspendRequested:=true; end;[/b] procedure TMeinThread.execute; var i: integer; begin while not terminated do begin [b]form1.Memo1.Lines.Add(inttostr(i));[/b] if SuspendRequested then suspend; i := i + 1; sleep(500); end; end; Wenn Du FreeonTerminate auf True setzt um alles nachher aufgeräumt zu haben, solltest Du beachten, dass Threads die suspended sind niemals freigegeben werden, da die execute methode nicht zu ende laufen kann. Dies müsstest Du ebenfalls selber ausprogrammieren, indem Du bei Terminate einen suspendeten Tread zuerst wieder resumest, damit er zuende laufen kann. Achtung bei verschachtelten Suspends, diese müssen ALLE wieder mit resume aufgehoben werden. Hoffe das hilft Dir ein Bisschen weiter. Viele Grüsse |
Re: Threads Suspend -> Resume ... wo gehts weiter?
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Delphi-Quellcode:
... wie oben beschrieben. So kann man garantieren, daß erst ein Schleifendurchlauf durch ist, bevor man wieder neu beginnt (durch Resume von außen). Außerdem sollte die Suspended-Property nur von außen Sinn machen, da Execute ja nicht ausgeführt wird und damit auch nicht die Prüfung ob Suspended oder nicht. Man könnte es also genausogut durch ein while(true)do; ersetzen ;)
procedure TThread.Execute();
begin while not Terminated do begin //Machwas; Suspend(); // Am Ende der Schleife schlafenlegen ... end; end; Zitat:
Zitat:
Zitat:
|
Re: Threads Suspend -> Resume ... wo gehts weiter?
Zitat:
|
Re: Threads Suspend -> Resume ... wo gehts weiter?
Zitat:
|
Re: Threads Suspend -> Resume ... wo gehts weiter?
Normalerweiser erzeugt man das Thread-Objekt um angahltenen Zustand, setzt dann die Eigenschaften, unteranderem eben auch FreeOnTerminate, und ruft dann die Methode Resume auf.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:27 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