![]() |
Multithread Einstellungsobjekt refreshen
Also Ich habe da ein Einstellungsobjekt MyConfig.
-Das Objekt kann sich in eine INI-File schreiben oder von dort auslesen. -Das Eigenschaften des Objekts werdn von etlichen Hintergrund-Threads permanent gelesen. -Es gibt nur einen Thread der auf das Objekt schreibend zu greift und das auch nur sehr selten, also vielleicht alle paar Monate mal. Im Idealfall nur einmal in der Lebensdauer der Anwendung. Ich möchte nicht jeden Lese/schreib Zugriff mit einer Critical section versehen, weil schreibzugriffe soooo selten sind. Aber ich will trotzdem sicher sein das die funktionieren. Gibt es 'ne Möglichkeit eine Unterbrechung für diesen kurzen seltenen Moment global Anwendnungsweit zu verhindern? Sprich alle Threads einzufrieren außer einem. Ist die Lösung alle Threads zu terminieren? Das wäre echt schade. |
AW: Multithread Einstellungsobjekt refreshen
![]() Und nein, Threads anzuhalten ist keine Lösung, darum ist das auch beim TThread "verboten" (es sei denn, man baut in jeden Thread einen Code ein, womit jeder Thread sich selbet "definiert" anhält) |
AW: Multithread Einstellungsobjekt refreshen
Danke!!!
Gucke mir das jetzt erst mal an, aber der Name hört sich vielversprechend an. |
AW: Multithread Einstellungsobjekt refreshen
Wenn jeder Thread beim Erzeugen eine Kopie von MyConfig bekommt, dann wäre zumindest das Problem mit dem Mehrfachzugriff geregelt.
Noch besser wäre, wenn jeder Thread nur die Daten bekommt, die er auch braucht! Wenn irgendjemand Geld vor dir möchte, dann gibst du ihm ja auch nicht deine Geldbörse mit Bargeld, Kredit- und Visitenkarten, sondern du gibst ihm nur die Geldmenge die er haben will. Aus dem gleichen Grund ist es unfein globale Objekte an Threads zu geben. Fiktives Beispiel:
Delphi-Quellcode:
function CreateAndStartDatenleseThread: TDatenleseThread;
begin Result := TDatenleseThread.Create; Result.ComPort := MyConfig.ComPort; Result.Baudrate := MyConfig.Baudrate; ... Result.Resume; end |
AW: Multithread Einstellungsobjekt refreshen
Zitat:
Was passiert wenn ich BeginWrites im selben threat kaskadiere?
Delphi-Quellcode:
Oder BeginReads im WriteLock block des selben threads nutze?
BeginWrite;
BeginWrite; EndWrite; EndWrite;
Delphi-Quellcode:
geht das?
BeginWrite;
BeginRead; EndRead; EndWrite; Eine Sache wäre da noch. Gibt es 'ne Möglichkeit threadsichere Getter und Setter für Published Properties automatisch zu erzeugen? Oder gibt es ein "Synchronized", "Threadsafe" oder "Atomic" Flag oder so für Properties? |
AW: Multithread Einstellungsobjekt refreshen
In einem Thread ist es erstmal grundsätzlich egal, ob man BeginRead und BeginWrite verschachtelt.
Aber es könnte zu einem DeadLock führen, wenn mehrere Thread sowas machen. Jedenfalls muß/sollte man bei einer Verschachtelung immer das "Höherwertige" zuerst sperren. höherwertig/restriktiv = Write niederwertig/extensiv = Read keine Probleme
Delphi-Quellcode:
Wenn aber zwei/mehrere Threads das machen, was Thread 2 macht,
Thread 1:
BeginRead ... EndRead Thread 2: BeginRead ... BeginWrite ... EndWrite ... EndRead dann würden alle Threads bei BeginWrite für immer auf die jeweils Anderen warten, welche gleichzeitig via BeginRead gesperrt haben, wärend sie auf BeginWrite warten, da BeginWrite darauf wartet, daß sich kein anderer Thread im Lese- und Schreibzugriff befindet. Das Selbe geschieht auch, wenn man z.B. zwei/mehrere CriticalSections verschachtelt ... auch da muß man überall die CS in der selben Reihenfolge sperren und muß immer alle "höheren" mit sperren. z.B. CS1, CS2 und CS3 müssen immer in dieser Reihenfolge gesperrt wernden und selbst wenn man nur CS2 braucht, dann muß dennoch vorher CS1 gesperrt werden, damit kein DeadLock entstehen kann. |
AW: Multithread Einstellungsobjekt refreshen
Eine CriticalSection regelt nicht nur den Zugriff sondern hilft auch dabei konsistente Daten auszutauschen.
Dieses funktioniert bei MultiReadExclusiveWrite nicht, denn wenn der Comport schon geändert wurde, aber noch nicht die Baudrate, etc. dann habe ich inkonsistente Daten. Mein Vorschlag: Der Schreiber-Thread sperrt zum Schreiben das Config-Objekt über eine CS, trägt alle Daten ein und gibt die Sperre wieder frei. Die Leser-Threads holen sich von dem Config-Objekt eine Kopie ab und lesen von dort die Einstellungen. Der Leser-Thread entscheidet nun, zu welchem Zeitpunkt er die Daten haben will. Dazu bietet das Config-Objekt zwei Methoden an: 1. Config-Daten nur dann kopieren, wenn es nicht gesperrt ist (CS.TryEnter) 2. Config-Daten kopieren erzwingen, auch wenn man warten müsste (CS.Enter) Der Thread kann sich nun entscheiden, ob er sich bremsen lassen will, oder es hinnehmen kann mit den "alten" Daten zu arbeiten (die vor ein paar Millisekunden noch "aktuell" waren) |
AW: Multithread Einstellungsobjekt refreshen
Zitat:
Wenn etwas "gemeinsam" (zusammenhängend) gesetzt oder ausgelesen werden muß, dann muß man dieses auch gemainsam schützen/blockieren und das trifft sowohl auf die CS, als auch auf den MREW zu. |
AW: Multithread Einstellungsobjekt refreshen
Zitat:
Allerdings halte ich es für unerlässlich, dass jeder Thread eine Kopie der Daten hat, denn nur der Thread selber kann entscheiden, wann er bereit für eine neue Config ist und kann diese dann abholen. Wird dort gerade die Config überarbeitet, dann wartet er (und alle anderen) solange, bis dort gelesen werden kann. |
AW: Multithread Einstellungsobjekt refreshen
Zitat:
Die Kopie würde dann über ein Dirtyflag anzeigen können das sie veraltet ist und eine Refresh Funktion könnte dann vom Thread aufgerufen die Kopie aktualisieren. So hätte ich konsistente und Lesevorgänge und sichere Schreibvorgänge. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:09 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