![]() |
Viele Threads untereinander synchronisieren
Hallo!
Ich habe folgendes (merkwürdige) Problem: In einem Thread werden Werte an andere Threads vergeben. Diese Threads werden vom Mainthread ausgeführt. Der Thread, der Werte an die anderen Threads senden soll, hat eine Liste von Objekten, welche eine Referenz zu den anderen Threads halten. Wenn ich also dieses Signal an alle Threads in der Liste senden will, müsste ich prinzipiell sowas machen:
Delphi-Quellcode:
Dabei ist zu beachten, dass die Objekte in der Liste dem Thread gehören, auf den mit "OwnedThread" zugegriffen wird.
procedure TMyThread.EmitSignal;
var i: Integer; begin for i:=0 to objlist.Count-1 do objlist[i].OwnedThread.ReceiveSignal(); end; So. Und jetzt soll die Funktion oben aber nicht so aufgerufen werden, sondern ordentlich mit dem Thread Synchronisiert werden. Denkbar wäre sowas:
Delphi-Quellcode:
Und hier sieht man das Problem: Wie hole ich den korrekten Thread aus der Liste, und synchronisiere die Funktionen richtig? Dummerweise akzeptiert TThread.Synchronize ja nur Methoden vom Typ TThreadMethod und keine lokalen.
procedure TMyThread.EmitSignal();
begin Synchronize(objlist[?].OwnedThread,@SyncSignal); end; procedure TMyThread.SyncSignal; begin objlist[?].OwnedThread.ReceiveSignal(); end; Weiß jemand da eine gute Lösung für? |
Re: Viele Threads untereinander synchronisieren
Synchronize dient dazu, Methoden im Kontext des Hauptthreads auszuführen.
Mir ist keine Methode bekannt, die so etwas für Threads untereinander implementiert. Es bietet sich an, die Methode ReceiveSignal jeweils threadsicher zu programmieren (z.B. mit kritischen Abschnitten). |
Re: Viele Threads untereinander synchronisieren
Und wofür genau ist dann
Delphi-Quellcode:
?
class procedure Synchronize(AThread: TThread; AMethod: TThreadMethod);
Kritische Abschnitte - wie funktioniert das genau mit Delphi? Gibt es da eine Anleitung zu? |
Re: Viele Threads untereinander synchronisieren
Zitat:
Zitat:
Zitat:
Die Hilfe ist dazu leider ziemlich kurz. Im Forum wirst du aber einige Beiträge finden, z.B. diese: ![]() ![]() |
Re: Viele Threads untereinander synchronisieren
Liste der Anhänge anzeigen (Anzahl: 1)
Hier ein paar einfache Beispiele, um sich die Grundlagen für CriticalSections, TMultiReadExclusiveWriteSynchronizer und dem Gebrauch eines Mutex
anzueignen ... ein Thread liest Daten, der andere Thread schreibt Daten. Das muss synchronisiert werden Am besten mit dem Beispiel ThreadsNoSync anfangen, damit man sieht, wie es nicht geht und was passieren kann, wenn man die Synchronisation nicht beachtet. |
Re: Viele Threads untereinander synchronisieren
Zitat:
Ich lese mir das mal durch... Eine "einfachere" Möglichkeit scheint es nicht zu geben, oder? |
Re: Viele Threads untereinander synchronisieren
Zitat:
|
Re: Viele Threads untereinander synchronisieren
Ja, die probiere ich grade auch aus.
Muss das TCriticalSection-Objekt eine globale variable sein? Oder kann jeder Thread eine eigene Instanz verwenden? |
Re: Viele Threads untereinander synchronisieren
Zitat:
Alle schreibenden Funktionen auf irgendwelche Daten und alle Lesenden Funktionen müssen syncrhonisiert werden. Auch wenn es nur ein "kleiner" Integer Wert ist. Weil es passieren kann, dass halbe Daten, und damit ungültige Daten gelesen und geschrieben werden. Kleine Ausnahme .. booleans kann man auch so schreiben. Die werden mit einem Prozessorbefehl gelesen, da kann man nix falsch machen. Wenn Du also ein "Datenobject" hast .. was alle schreib und leseaufträge empfängt, dann muss nur dieses eine Object die Daten syncrhonizieren .. viele Threads dürfen dann dort reinschreiben und müssen selbst gar nix beachten mit der Synchronization, wenn sie über Write und Read Properties, Funktionen Daten dort reinschreiben .. .. ich hätte Dir gern noch ein schönes Beispiel von mir geschickt, bin mir aber nicht sicher ob das das richtige war. Wir hatten nämlich auch ein Beispiel, was auf einer 8 Core XEON Cpu versagt hat. Weiß jetzt nicht, welches das war in dem Ordner.. hmmm .. nochmal editiert.. |
Re: Viele Threads untereinander synchronisieren
Mein problem ist ja eigentlich folgendes: Ich entwickle eine wissenschaftliche Anwendung, welche dummerweise diese ganzen Threads braucht. (es geht um eine Biosimulation)
Allerdings funktioniert das zusammenspiel manchmal, aber maistens empfängt die Anwendung ein SIGFPE- oder SIGSEGV-Signal (ich nutze Linux). Der Debugger kann die Fehlerstelle nicht finden und die Assemblerdaten sind wertlos. Also will ich erstmal allen Threads beibringen, ihre Daten "richtig" auszutauschen. Nochmal konkreter: Ich habe zwei Threads und ein "Zwischenobjekt". Beide Threads machen Berechnungen im Mainloop. Thread2 hält das Zwischenobjekt, Thread1 hat eine Referenz drauf. Thread1 sendet nun Informationen an Thread2, indem eine Funktion im Zwischenobjekt aufgerufen wird, welche die Daten kurz ändert und dann an Thread2 weitergibt. Dies kann immer passieren, auch wenn Thread2 Suspended ist, Ist Thread2 Suspended und empfängt grade ein Signal, so wird Resume() ausgeführt. Reicht es also, die CriticalSections im Zwischenobjekt bei der Übertragung auf den Thread2 anzubringen, oder müssen die vorher schon sein, da ja Daten von Thread1 in einem Objekt verändert werden, was Thread2 gehört? (veränderung erfolgt durch Aufruf der Methode des Zwischenobjektes) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:24 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