AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

TThread.Synchronize

Ein Thema von Der schöne Günther · begonnen am 14. Mär 2013 · letzter Beitrag vom 15. Mär 2013
Antwort Antwort
Seite 1 von 2  1 2      
Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

TThread.Synchronize

  Alt 14. Mär 2013, 19:03
Delphi-Version: XE2
Hallo-

Ich weiß dass schätzungsweise 20% des weltweiten Internet-Traffics von Fragen zu Delphi-Threads und Synchronize() verursacht werden, trotzdem finde ich nicht wirklich eine Antwort:

Überall sprechen die Leute nur davon, von einem Thread aus etwas im Kontext des Haupt-Threads auszuführen. Praktisch immer um ein VCL-Element zu aktualisieren. Ich möchte aber vom Hauptthread aus eine Methode im Kontext meines TThread-Objekts aufrufen. Besser noch: Eine lokale Variable auf dem Stack eines Threads A mit Werten füllen die ein Thread B in Erfahrung bringt.

In den letzten Tagen wusste ich noch nicht einmal, dass es ein Delphi TThread-Objekt gibt. Bislang bin ich immer direkt den Weg über die WinAPI mittels CreateThread/BeginThread und kritischen Abschnitten gegangen. Jetzt dachte ich, TThread sei unheimlich komfortabel.

Ich dachte, ich kann es einfach folgendermaßen über die Bühne bringen:
Delphi-Quellcode:
TThread.Synchronize(
   meinThread,
   procedure
   begin
      lokaleVariable := getWert();
   end
);
Das klappt nicht wirklich. Oder zumindest nicht, wie ich mir das vorgestellt habe: Mit diesem Aufruf ist anscheinend keineswegs sichergestellt, dass sich meinThread nicht auch grade durch getWert() wühlt, der darin dann unterbrochen wird, und anschließend der Kram noch einmal obendrauf ausgeführt wird? Denn danach sieht es mir aus...
Spontan hätte ich jetzt erwartet, dass TThread.Synchronize(meinThread, ...) erst einmal so lange blockiert, bis meinThread sich schlafen gelegt hat oder wenigstens nicht selbst gerade mittendrin in getWert() steckt!

Habe ich durch TThread überhaupt etwas gewonnen? Oder muss ich trotzdem wieder auf kritische Abschnitte und Pipes zurückgreifen?

Geändert von Der schöne Günther (14. Mär 2013 um 20:22 Uhr) Grund: Im Vollrausch geschriebene Sätze neu formuliert
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.625 Beiträge
 
Delphi 12 Athens
 
#2

AW: TThread.Synchronize

  Alt 14. Mär 2013, 19:22
Synchronize wird vom TThread-Objekt aufgerufen, nicht aus dem Hauptthread heraus. Du kannst Daten zwischen den Threads z.B. mittels Events oder Messages austauschen.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: TThread.Synchronize

  Alt 14. Mär 2013, 19:47
Zur Syncronisation habe ich hier mal ein kleines übersichtliches Beispiel.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: TThread.Synchronize

  Alt 14. Mär 2013, 20:23
Hallo -

Ich entschuldige mich für den Sauhaufen an Buchstaben, ich war schon halb durch die Tür. Deswegen hat man wahrscheinlich nicht ganz verstanden, was meine Frage ist. Hoffentlich ist es jetzt klarer.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: TThread.Synchronize

  Alt 14. Mär 2013, 21:13
Wichtig ist hierbei auch der Blick in die Dokumentation TThread.Synchronize.
Zitat von TThread.Synchronize:
Führt einen Methodenaufruf im Haupt-Thread aus.
Also egal von wo auch immer das ausgeführt wird, es wird synchron zum Hauptthread ausgeführt.

Greift dabei auf etwas zu was von einem anderen Threadkontext auch benutzt werden kann, dann kann es knallen.

Also entweder alles immer über den Hauptthread synchronisieren (ja, ist doof) oder die Zugriffe mit Delphi-Referenz durchsuchenTCriticalSection sichern.

Erzähl doch mal, was die Threads machen sollen, evtl. kann man das auch mit Bei Google suchenOmniThreadLibrary stressfreier lösen
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#6

AW: TThread.Synchronize

  Alt 15. Mär 2013, 07:58
[QUOTE=Der schöne Günther;1207437
Habe ich durch TThread überhaupt etwas gewonnen? Oder muss ich trotzdem wieder auf kritische Abschnitte und Pipes zurückgreifen?[/QUOTE] Na, die Klasse kapselt die Thread-Funktionalität. Du definierst das Verhalten des Threads, also:
1. Wie bzw. womit wird er initialisiert? (Konstruktor)
2. Was soll er im Hintergrund machen? (Execute-Methode)
3. Was soll passieren, wenn er fertig ist. (OnTerminate-Event)

Bei Punkt 2 kommt dann die Synchronize-Geschichte ins Spiel. Hiermit kannst Du z.B. Statusanzeigen umsetzen. Wichtig ist hier, das Synchronize so lange wartet, bis der Hauptthread sich drum kümmern kann. Es geht also Zeit flöten.

Der Datenaustausch zwischen dem Thread und anderen Threads erfolgt meist über Eigenschaften, deren Setter und Getter mit kritischen Abschnitten (CS) vor konkgruenten Zugriffen schützt.

Ein Thread kann einem anderen Thread auch über Messages oder Events mitteilen, das irgend etwas passiert ist (ein Milestone, Zwischenergebnis o.ä.). Der andere Thread holt sich dann die Daten ab (über CS gesichert) und verarbeitet die dann weiter.
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: TThread.Synchronize

  Alt 15. Mär 2013, 08:37
Vielen Dank für die Antworten!

Wichtig ist hierbei auch der Blick in die Dokumentation TThread.Synchronize.
Zitat von TThread.Synchronize:
Führt einen Methodenaufruf im Haupt-Thread aus.
Also egal von wo auch immer das ausgeführt wird, es wird synchron zum Hauptthread ausgeführt.
Wenig später heißt es jedoch:
Zitat:
Hinweis: Wenn Sie die statische Version der Methode Synchronize mit nil/NULL als der erste Parameter verwenden, wird die von AMethod referenzierte Methode im Haupt-Thread synchronisiert.
Das hatte ich bislang so interpretiert, als könnte ich mit der gleichnamigen Klassenmethode angeben, von welchem Thread aus der Aufruf tatsächlich stattfindet. Denn wozu gebe ich einen Thread sonst überhaupt als Parameter an?

Wichtig ist hier, das Synchronize so lange wartet, bis der Hauptthread sich drum kümmern kann. Es geht also Zeit flöten.
Gut (und beruhigend) zu wissen. Aber gerade hier beschleicht mich jetzt das Gefühl, dass ich meinen TThread noch mit irgendwas hätte ausstatten müssen, um darauf überhaupt (und auch wo) zu reagieren - Eine Art kümmereDichUmSynchronize-AufrufeVonAnderenThreads() .


Um kritische Abschnitte gibt es dann wohl wieder keinen Weg drum herum, ich möchte nicht, dass die Funktion "von außen" aufgerufen/angefordert wird, wenn der Thread selbst auch gerade in dieser Funktion wühlt. Jetzt bin ich mal gespannt, was TCriticalSection bereithält...
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

AW: TThread.Synchronize

  Alt 15. Mär 2013, 08:48
Was soll Delphi-Referenz durchsuchenTCriticalSection schon bereithalten?

Betreten oder Versuchen zu betreten, Verlassen that's all
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#9

AW: TThread.Synchronize

  Alt 15. Mär 2013, 09:05
Und es funktioniert sogar, der Tag ist gerettet.

Im Endeffekt bin ich zwar immer noch etwas ratlos, was für konkrete Vorteile es mir bringt, nicht direkt über die WinAPI zu gehen, aber das wird sich sicher noch zeigen.

Geändert von Der schöne Günther (15. Mär 2013 um 09:09 Uhr)
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#10

AW: TThread.Synchronize

  Alt 15. Mär 2013, 09:33
Ich bin von Synchronize mittlerweile ganz weg. Wenn ich im Thread API Ressourcen brauche erstelle ich sie mir dort (nicht als Kompo auf dem Formular z.B.), Threads teilen sich nur via PostMessage mit, und haben Properties deren Getter und Setter mit jeweiligen Critical Sections versehen sind. Zwar wimmelt es in der Thread-Methode je nach Fall von CS.Enter; try ... finally CS.Leave; end; , aber so muss das Hauptprogramm nachher nicht mehr machen, als die Messages zu emfangen und kann einfach so auf den Feldern des Threads agieren. (Üblicherweise dann Work-Queues und erweiterte Status-Objekte o.ä.)

Ist etwas mehr Tipperei, aber seit ich das so durchziehe habe ich nie wieder einen Thread gegen die Wand fahren lassen.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  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 00:44 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