AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi TThread: Daten von Mainthread holen --> Synchronize notwendig?
Thema durchsuchen
Ansicht
Themen-Optionen

TThread: Daten von Mainthread holen --> Synchronize notwendig?

Ein Thema von Helmi · begonnen am 18. Dez 2024 · letzter Beitrag vom 18. Dez 2024
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Helmi
Helmi

Registriert seit: 29. Dez 2003
Ort: Erding, Republik Bayern
3.336 Beiträge
 
Delphi XE2 Professional
 
#1

TThread: Daten von Mainthread holen --> Synchronize notwendig?

  Alt 18. Dez 2024, 07:22
Hallo Zusammen,

wenn man in einem Thread etwas an den Mainthread/VCL/GUI schicken möchte, dann muss man Synchronize verwenden.
Ist dies auch notwendig, wenn man sich Daten aus dem Mainthread holt?

In meinem Falle lasse ich mir einen String übergeben.
Dazu hab ich in der Thread-Unit eine function, die eine function im Mainthread aufruft und über die wird der String übergeben.
mfg
Helmi

>> Theorie ist Wissen, dass nicht funktioniert - Praxis ist, wenn alles funktioniert und keiner weiss warum! <<
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.648 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: TThread: Daten von Mainthread holen --> Synchronize notwendig?

  Alt 18. Dez 2024, 07:29
Du musst den Zugriff absichern, aber du kannst auch einfach TMonitor verwenden:
Delphi-Quellcode:
TMonitor.Enter(MyThread); // oder ein anderes Objekt
try
  MyThread.Value := 'Test';
finally
  TMonitor.Exit(MyThread);
end;
Wenn du jeden Zugriff auf den Wert (Schreiben + Lesen) so absicherst, brauchst du kein Synchronize, was viel aufwendiger ist.

Synchronize brauchst du nur, wenn du etwas wirklich im Kontext eines anderen Threads durchführen musst. Dazu zählt z.B. eine Callback-Funktion, die aus einem Threrad aufgerufen wird, und z.B. auf eine Datenbank oder die GUI zugreifen möchte. Wenn du lediglich die Zugriffe absichern musst, ist das nicht nötig.

Und wenn ein Wert oft gelesen, aber nur selten geschrieben wird, gibt es noch den TMultiReadExclusiveWriteSynchronizer, der dies optimiert. Da ist dann lediglich die (seltene) Schreiboperation teuer, aber das Lesen geht schnell.
Sebastian Jänicke
AppCentral

Geändert von jaenicke (18. Dez 2024 um 07:33 Uhr)
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.116 Beiträge
 
Delphi 12 Athens
 
#3

AW: TThread: Daten von Mainthread holen --> Synchronize notwendig?

  Alt 18. Dez 2024, 07:51
Hier etwas alternativer Lesestoff zu TThreadedQueue über die Weihnachtszeit, TL;DR

https://ideasawakened.com/post/revis...itor-in-delphi
https://en.delphipraxis.net/topic/28...-and-tmonitor/
  Mit Zitat antworten Zitat
Benutzerbild von Helmi
Helmi

Registriert seit: 29. Dez 2003
Ort: Erding, Republik Bayern
3.336 Beiträge
 
Delphi XE2 Professional
 
#4

AW: TThread: Daten von Mainthread holen --> Synchronize notwendig?

  Alt 18. Dez 2024, 08:26
Du musst den Zugriff absichern, aber du kannst auch einfach TMonitor verwenden:
Delphi-Quellcode:
TMonitor.Enter(MyThread); // oder ein anderes Objekt
try
  MyThread.Value := 'Test';
finally
  TMonitor.Exit(MyThread);
end;
Wenn du jeden Zugriff auf den Wert (Schreiben + Lesen) so absicherst, brauchst du kein Synchronize, was viel aufwendiger ist.
Wenn ich dich jetzt (hoffentlich) richtig versteh, dann reicht es aus, im Mainthread/GUI in den proceduren, die vom Thread aufgerufen werden, jeweils TMonitor aufzurufen, in dem dann z. B. der String an den Thread übergeben wird, bzw. z. B. die GUI mit den Daten versorgt wird, die vom Thread kommen?
mfg
Helmi

>> Theorie ist Wissen, dass nicht funktioniert - Praxis ist, wenn alles funktioniert und keiner weiss warum! <<
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.648 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: TThread: Daten von Mainthread holen --> Synchronize notwendig?

  Alt 18. Dez 2024, 09:29
Du musst alle Zugriffe entsprechend absichern. Beispiel:
Delphi-Quellcode:
// Hauptthread:
TFormA = class(TForm)
private
  FValue: string;
...
end;

procedure TFormA.Example;
begin
  TMonitor.Enter(Self);
  try
    FValue := 'Test';
  finally
    TMonitor.Exit(Self);
  end;
end;

// vom Thread aufgerufen:
function TFormA.ThreadCallback: string;
begin
  TMonitor.Enter(Self);
  try
    Result := FValue;
  finally
    TMonitor.Exit(Self);
  end;
end;
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Benutzerbild von Helmi
Helmi

Registriert seit: 29. Dez 2003
Ort: Erding, Republik Bayern
3.336 Beiträge
 
Delphi XE2 Professional
 
#6

AW: TThread: Daten von Mainthread holen --> Synchronize notwendig?

  Alt 18. Dez 2024, 10:31
Du musst alle Zugriffe entsprechend absichern. Beispiel:
Dank dir - dann hatte ich es richtig verstanden.
Auf das Synchronize hab ich Thread kann ich dann verzichten

Bei mir schauts dann so aus:
Delphi-Quellcode:
procedure TMainForm.Thread_UDP_ReceiveString(var Text: String);
begin
  Text := '';

  System.TMonitor.Enter(ClientThread);

  try
    If idUDPClient.Connected then
      Text := IdUDPClient.ReceiveString(-1, TEncoding.UTF8);

  finally
    System.TMonitor.Exit(ClientThread);
  end;
end;

procedure TMainForm.Thread_Daten(const Text: String);
begin
  System.TMonitor.Enter(ClientThread);

  try
    InfoForm.InfoText := Text;
  finally
    System.TMonitor.Exit(ClientThread);
  end;
end;
mfg
Helmi

>> Theorie ist Wissen, dass nicht funktioniert - Praxis ist, wenn alles funktioniert und keiner weiss warum! <<
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#7

AW: TThread: Daten von Mainthread holen --> Synchronize notwendig?

  Alt 18. Dez 2024, 11:29
Jupp, natürlich all, auch die innerhalb des Hauptthreads.

Zitat:
System.TMonitor
Und den Namespace, weil die Idioten dieses TMonitor blind eingebaut hatten, nachdem es schon Jahrzehnte lang bereits ein anderes TMonitor gab/gibt, was aber was ganz anderes ist (Bildschirme).

Beim Syncronize und Queue mußt du nur alles in Threads absichern rüberschieben, in den Hauptthread, was nicht im Hauptthread ist, dann das im Hauptthread ist ja bereits dort.

Und für Integer/Int64/Cardinal/UInt64/Word/LongBool und andere 2, 4 bzw. 8 Byte große "einfache" Typen, wie z.B. ENUMs, gibt es auch Funktionen aus CPU-Ebene Systemebene,
wo beim Schreiben alle anderen Schreib- und Lesevorgänge gesperrt/pausiert sind.

Delphi-Referenz durchsuchenInterlockedExchange oder besser Delphi-Referenz durchsuchenAtomicExchange
InterlockedCompareExchange / AtomicCmpExchange
InterlockedExchange64
InterlockedExchangePointer
InterlockedDecrement / AtomicDecrement
InterlockedIncrement / AtomicIncrement
uvm.
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von Helmi
Helmi

Registriert seit: 29. Dez 2003
Ort: Erding, Republik Bayern
3.336 Beiträge
 
Delphi XE2 Professional
 
#8

AW: TThread: Daten von Mainthread holen --> Synchronize notwendig?

  Alt 18. Dez 2024, 11:37
Jupp, natürlich all, auch die innerhalb des Hauptthreads.

Zitat:
System.TMonitor
Und den Namespace, weil die Idioten dieses TMonitor blind eingebaut hatten, nachdem es schon Jahrzehnte lang bereits ein anderes TMonitor gab/gibt, was aber was ganz anderes ist (Bildschirme).
Dachte zuerst, dass mein XE2 noch nicht TMonitor für Threads kennt, bis ich irgendwo gelesen hab, dass es das seit 2009 gibt.
Bin auch anfangs erst mal bei Bildschirme rausgekommen, daher System.TMonitor.

Beim Syncronize und Queue mußt du nur alles in Threads absichern rüberschieben, in den Hauptthread, was nicht im Hauptthread ist, dann das im Hauptthread ist ja bereits dort.
Ich hab jetzt mehrmals den Satz gelesen und habe mehrmals nicht verstanden, was du mir damit sagen willst.
mfg
Helmi

>> Theorie ist Wissen, dass nicht funktioniert - Praxis ist, wenn alles funktioniert und keiner weiss warum! <<
  Mit Zitat antworten Zitat
TomyN

Registriert seit: 8. Nov 2006
Ort: Bayreuth
252 Beiträge
 
Delphi 10.3 Rio
 
#9

AW: TThread: Daten von Mainthread holen --> Synchronize notwendig?

  Alt 18. Dez 2024, 14:35
Hi,

Ich hänge mich mal hier mit dran. Normalerweise synchronisiere ich mit einer Mutex oder einer CriticalSection.
Was sind da die Unterschiede? Beim TMonitor brauch ich wohl keine globale variable für die Mutex oder?
Thomas Neumann
Meine Projekte
www.satlive.audio
www.levelcheck.de
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.648 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: TThread: Daten von Mainthread holen --> Synchronize notwendig?

  Alt 18. Dez 2024, 17:38
Bei mir schauts dann so aus:
Delphi-Quellcode:
procedure TMainForm.Thread_UDP_ReceiveString(var Text: String);
begin
  Text := '';

  System.TMonitor.Enter(ClientThread);

  try
    If idUDPClient.Connected then
      Text := IdUDPClient.ReceiveString(-1, TEncoding.UTF8);

  finally
    System.TMonitor.Exit(ClientThread);
  end;
end;
Dann führst du das ReceiveString aber auch innerhalb des Locks aus, obwohl es dafür gar keinen Grund gibt. Besser ist es, wenn du alles fertig machst und dann nur noch in dem abgesicherten Teil die Zielvariable schreibst.

Denn je länger du Threads blockierst, desto eher übersiehst du mögliche Deadlocks, sprich dass sich zwei Threads gegenseitig blockieren, weil beide auf den anderen warten (z.B. einer im TMonitor.Enter, der andere in einem Synchronize, jetzt nur als Beispiel). Die Gefahr besteht hier nicht, aber trotzdem sollte man in einem Lock, sprich hier zwischen Enter und Exit, so wenig Code wie möglich ausführen.

Ich hänge mich mal hier mit dran. Normalerweise synchronisiere ich mit einer Mutex oder einer CriticalSection.
Was sind da die Unterschiede? Beim TMonitor brauch ich wohl keine globale variable für die Mutex oder?
TMonitor funktioniert über eine Objektreferenz. Auf die brauchst du also auch Zugriff. Innerhalb eines Objekts geht das mit Self sehr einfach.

Eine TCriticalSection ist tendentiell etwas schneller, ein Mutex sehr viel langsamer, da dieser über den Kernel läuft. Einen Mutex sollte man nur zur Interprozesskommunikation nutzen, nicht innerhalb eines Prozesses.

Wenn es um beste Performance geht, ist eine TCriticalSection meistens am besten. Wenn du das bisher so machst, ist das völlig in Ordnung. TMonitor ist aber einfacher zu nutzen, wenn man im Kontext eines Objekts ist, weshalb ich das trotzdem gerne nutze. Bei den meisten Anwendungsfällen wird der Performanceunterschied keine Rolle spielen.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:51 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