Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   TThread.synchronize atomar? (https://www.delphipraxis.net/211228-tthread-synchronize-atomar.html)

Olli73 18. Aug 2022 14:45

Delphi-Version: 10.2 Tokyo

TThread.synchronize atomar?
 
Hallo!

Läuft die Prozedur in "TThread.Synchronize(nil, procedure ...)" im Hauptthread atomar ab oder kann da ein anderer Thread durch synchronize "dazwischen grätschen"?

LG
Olli

Uwe Raabe 18. Aug 2022 15:09

AW: TThread.synchronize atomar?
 
Zitat:

Zitat von Olli73 (Beitrag 1510266)
Läuft die Prozedur in "TThread.Synchronize(nil, procedure ...)" im Hauptthread atomar ab oder kann da ein anderer Thread durch synchronize "dazwischen grätschen"?

In einem Thread läuft immer alles atomar ab, wobei das hier der falsche Ausdruck ist. Da kann nichts dazwischen grätschen (wenn man von Hardware Interrupts und ähnlichem absieht).
Delphi-Quellcode:
Synchronize
setzt bildlich gesprochen ein Flag das der Hauptthread zyklisch abprüft und den entsprechenden Code ausführt. Der aufrufende Thread wartet solange. Wenn mehrere Threads ein Synchronize aufrufen (jeder kann nur eins), werden die im Hauptthread sequentiell abgearbeitet - wie alles in einem Thread.

Von atomar spricht man im Zusammenhang mit Zugriff auf gemeinsame Ressourcen (z.B. einer Variable). Hier gilt eine Operation als atomar, wenn sie durch keinen anderen Thread unterbrochen werden kann, womit das Resultat verfälscht werden könnte.

Olli73 18. Aug 2022 15:16

AW: TThread.synchronize atomar?
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1510268)
Wenn mehrere Threads ein Synchronize aufrufen (jeder kann nur eins), werden die im Hauptthread sequentiell abgearbeitet - wie alles in einem Thread.

Danke. Das "sequentiell" ist für mich das Entscheidende. Der Codeblock (die anonyme Prozedur) wird also am Stück ausgeführt und nicht durch Code von anderen Threads mit Synchronize unterbrochen.

Uwe Raabe 18. Aug 2022 15:47

AW: TThread.synchronize atomar?
 
Zitat:

Zitat von Olli73 (Beitrag 1510269)
Der Codeblock (die anonyme Prozedur) wird also am Stück ausgeführt und nicht durch Code von anderen Threads mit Synchronize unterbrochen.

Ja, wenn nicht innerhalb des Codeblocks sowas wie Application.ProcessMessages aufgerufen wird - auch nicht indirekt. Aber sowas macht heutzutage ja keiner mehr...

Eigentlich sollte die Methode FühreIrgendwelchenCodeAusDerWasAuchImmerMachenKann UndDenGanzenProgrammablaufUnvorhersehbarMacht heißen.

himitsu 18. Aug 2022 16:36

AW: TThread.synchronize atomar?
 
Zitat:

Zitat von Olli73 (Beitrag 1510269)
Der Codeblock (die anonyme Prozedur) wird also am Stück ausgeführt und nicht durch Code von anderen Threads mit Synchronize unterbrochen.

Ja,


AUßER, du lässt zu, dass sowas gemacht werden darf.


z.B. Application.ProcessMessages; aufrufen,
ebenso innerhalb einen ShowModal, ShowMessage/MessageBox oder nahezu allem Anderen, worin angefallene Messages verarbeitet werden.

Aber hier hält dann auch wieder dein Hauptthrad dort an und die Anderen laufen darin sequentiell ab.


ps: In einem ButtonClick eine Schleife, darin Application.ProcessMessages und schon kannst du innerhalb des OnClicks nochmal auf den Button klicken usw.

himitsu 18. Aug 2022 17:20

AW: TThread.synchronize atomar?
 
Dort, wo du jetzt auf den Button klicken kannst, da könnte auch ein Synchronize rein kommen.

Text kopieren und im FormDesigner einer neuen VCL-Form ein beherztes Strg+V
Code:
object Timer1: TTimer
  OnTimer = Timer1Timer
  Left = 56
  Top = 24
end
object Button1: TButton
  Left = 40
  Top = 88
  Caption = 'Button1'
  TabOrder = 0
  OnClick = Button1Click
end
object Button2: TButton
  Left = 40
  Top = 128
  Caption = 'Button2'
  OnClick = Button2Click
end
object Memo1: TMemo
  Left = 160
  Top = 40
  Width = 345
  Height = 297
  ScrollBars = ssVertical
end
Timer und Buttons doppelt anklicken (oder den unteren Quellcode vorher in die PAS einfügen)
und die Funktionen mit folgendem ersetzen
Delphi-Quellcode:
var gutesC: Integer; // oder als Private in die Form

procedure TForm1.Button1Click(Sender: TObject);
begin
  Inc(gutesC);
  var C := gutesC;
  Memo1.Lines.Add('Button1-Start ' + C.ToString);
  for var i := 0 to 15 do begin
    Memo1.Lines.Add('Button ' + C.ToString + ' ' + i.ToString);
    Sleep(333);
    Application.ProcessMessages;
  end;
  Memo1.Lines.Add('Button1-Ende ' + C.ToString);
end;

var bösesI: Integer; // oder als Private in die Form
procedure TForm1.Button2Click(Sender: TObject);
begin
  Inc(gutesC);
  var C := gutesC;
  Memo1.Lines.Add('Button2-Start ' + C.ToString);
  repeat
    Inc(bösesI);
    Memo1.Lines.Add('Button ' + C.ToString + ' ' + bösesI.ToString);
    Sleep(333);
    Application.ProcessMessages;
  until bösesI mod 15 = 0;
  Memo1.Lines.Add('Button2-Ende ' + C.ToString);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Memo1.Lines.Add('Timer');
end;

Codes ab Delphi 10.irgendwas

Olli73 18. Aug 2022 17:32

AW: TThread.synchronize atomar?
 
Danke für den Hinweis auf ProcessMessages. Das mache ich zum Glück hier nicht. Ich hatte nur zusätzlich das Ganze mit TMonitor.Enter(...) innerhalb des Synchronize abgesichert - das ist dann ja unnötig.

Uwe Raabe 18. Aug 2022 18:45

AW: TThread.synchronize atomar?
 
Das Problem mit
Delphi-Quellcode:
Application.ProcessMessages
tritt ja auch ganz ohne Threads auf.

TurboMagic 18. Aug 2022 21:46

AW: TThread.synchronize atomar?
 
Zitat:

Zitat von himitsu (Beitrag 1510274)
Sleep(333);


Ah, 333, in Issus große Keilerei :lol:
Irgendwie treffend.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:49 Uhr.

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