![]() |
Delphi-Version: 10 Seattle
Allgemeine Fragen zu Threads
Hallo
ich habe mal ausgehend von dem Beispiel in ![]()
Delphi-Quellcode:
Meine Fragen:
unit fo_ThreadListDePraxis;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Generics.Collections, Vcl.Samples.Spin; type TForm1 = class(TForm) laSleeptime: TLabel; Memo1: TMemo; Button1: TButton; Button2: TButton; SpinEdit1: TSpinEdit; Label1: TLabel; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure Button2Click(Sender: TObject); procedure SpinEdit1Change(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; TMyList = class(TList<Integer>) end; TMyThread = class(TThread) private FCounter, FSleepTime: Integer; protected procedure Execute; override; public property SleepTime: Integer read FSleepTime write FSleepTime; end; var Form1: TForm1; MyList: TMyList; MyThread: TMyThread; implementation {$R *.dfm} procedure TForm1.Button2Click(Sender: TObject); begin if assigned(MyThread) then begin MyThread.Terminate; // Setzt MyThread nicht auf NIL, d.h. nächster Button2Click führt wieder in diesn Block Button2.Caption := 'Start Thread'; end else begin Button2.Caption := 'Terminate Thread'; MyThread := TMyThread.Create(true); // Create suspended--secondProcess does not run yet. MyThread.FreeOnTerminate := true; // You do not need to clean up after termination. MyThread.SleepTime := SpinEdit1.Value; MyThread.Resume; // Now run the thread. end; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin MyList.Free; MyThread.Terminate; end; procedure TForm1.FormCreate(Sender: TObject); begin MyList := TMyList.Create; end; procedure TForm1.SpinEdit1Change(Sender: TObject); begin if assigned(MyThread) then MyThread.SleepTime := SpinEdit1.Value; end; procedure TForm1.Button1Click(Sender: TObject); var i: Integer; begin for i := 0 to 20 do MyList.Add(random(200)); end; { TMyThread } procedure TMyThread.Execute; var i: Integer; begin inherited; while (true) do begin if Terminated then exit; inc(FCounter); Form1.Label1.Caption := IntToStr(FCounter); Form1.Memo1.Clear; System.TMonitor.Enter(MyList); // Liste gegen Zweitzugriff sperren. Muss das sein? try for i := 0 to MyList.Count - 1 do begin if Terminated then exit; Form1.Memo1.Lines.Add(format('%d: %d', [i, MyList.Items[i]])); // Ist das zulässig? end; finally System.TMonitor.exit(MyList); // Sperrung der Liste wieder aufheben end; sleep(FSleepTime); // FSleepTime oder besser SleepTime? end; end; end.
Danke für euer Feedback Gerd |
AW: Allgemeine Fragen zu Theads
Soweit ich (nun) weiß müssen lesende als auch schreibende Zugriffe geschützt werden.
Statt TMonitor würde ich aber CriticalSections benutzen. Die Ausführung ist weitaus schneller. Hier wird ja nur die Liste geschützt. Das Memo aber nicht. Das Emba-Beispiel ist keines, welches man sich "näher" ansehen sollte finde ich. |
AW: Allgemeine Fragen zu Theads
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
|
AW: Allgemeine Fragen zu Theads
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
...:cat:... |
AW: Allgemeine Fragen zu Theads
Wenn die Profis schon sprechen (ihr):
was haltet ihr denn von TMonitor und CriticalSections? Welches bevorzugt ihr? Soweit ich weiß hat CriticalSections weniger Overhead und ist deutlich schneller als TMonitor. Wenn ich darf habe ich auch eine grundlegende Frage zur Synchronisation: wenn man zwei Threads hat, beide greifen auf die VLC zu (Memo.Lines.Add) und man das synchronisiert, verliert man dann nicht den Vorteil den mehrere Threads eigentlich bieten sollten? |
AW: Allgemeine Fragen zu Theads
Zitat:
...:cat:... |
AW: Allgemeine Fragen zu Theads
Zitat:
...:cat:... |
AW: Allgemeine Fragen zu Theads
Hmmm..
Damit deine Thread-Variable auf nil gesetzt wird, brauchst Du so etwas: ( Und wieso die Globale Variable 'MyThread', obwohl nur innerhalb der Form darauf zugegriffen wird !!) ;)
Delphi-Quellcode:
TForm1 = class(TForm)
... procedure Button2Click(Sender: TObject); private procedure OnMyThreadTerminate(Sender: TObject); protected MyThread : TMyThread; public { Public-Deklarationen } end; procedure TForm1.Button2Click(Sender: TObject); begin if assigned(MyThread) then begin MyThread.Terminate; // Setzt MyThread nicht auf NIL, d.h. nächster Button2Click führt wieder in diesn Block Button2.Enabled := false; // Erst benutzbar machen, wenn Thread wirklich weg! end else begin Button2.Caption := 'Terminate Thread'; MyThread := TMyThread.Create(true); // Create suspended--secondProcess does not run yet. MyThread.FreeOnTerminate := true; // You do not need to clean up after termination. MyThread.OnTerminate := OnMyThreadTerminate; // Damit die Form benachrichtigt wird !!!! MyThread.SleepTime := SpinEdit1.Value; MyThread.Resume; // Now run the thread. end; end; procedure TForm1.OnMyThreadTerminate(Sender: TObject); begin if Sender = MyThread then begin MyThread := nil; // Nur nil, Free macht er selber! Button2.Caption := 'Start Thread'; Button2.Enabled := true; // Erst benutzbar machen, wenn Thread wirklich weg! end; end; |
AW: Allgemeine Fragen zu Theads
Zitat:
Zitat:
|
AW: Allgemeine Fragen zu Theads
Ihr seit einfach super.
Zitat:
Zitat:
Zitat:
Zitat:
Danke |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:10 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 by Thomas Breitkreuz