AW: Critical Section um globale Methode?
Zitat:
Wenn BeginRead nur dafür da ist zu verhindern, dass kein Write ausgeführt werden kann, lasse ich das vermutlich weg denn es gibt genau eine einzige Stelle an der geschrieben wird. |
AW: Critical Section um globale Methode?
Zitat:
Oder du kannst nicht ausschließen, dass jemand liest während du schreibst, dann musst du dies durch Sperren sicherstellen, in dem Fall durch den TMultiReadExclusiveWriteSynchronizer. Dann musst du dem aber auch sagen wann du lesen und wann schreiben möchtest, damit er diese Sperre auch durchführen kann. |
AW: Critical Section um globale Methode?
Ist bei mir ganz einfach: es ist exakt eine einzige Zeile Code im Multithread-System, die schreibenden Zugriff hat.
Es gibt eine weitere solche Zeile, die hat aber nichts mit Multithreading zu tun. Es ist egal von wo aus ich TMultiReadExclusiveWriteSynchronizer aufrufe, oder muss das aus dem Thread heraus sein der schreiben möchte? |
AW: Critical Section um globale Methode?
Zitat:
Du musst vor jedem Schreibvorgang BeginWrite aufrufen (ab da werden alle Schreib- und Lesezugriffe blockiert) und nach dessen Abschluss EndWrite (dann können wieder alle lesen). Vor jedem Lesevorgang musst du BeginRead aufrufen (ab da wartet BeginWrite, falls es danach aufgerufen wird, auf den Abschluss des Lesevorgangs) und nach dessen Abschluss EndRead (danach kehrt BeginWrite zurück, falls es nach BeginRead aufgerufen wurde. Auf diese Weise kann ein Schreibvorgang erst nach Abschluss aller laufenden Lesevorgänge passieren und neue Lesevorgänge erst nach dem Abschluss eines laufenden Schreibvorgangs. Solange aber niemand schreibt, können alle parallel lesen, d.h. BeginRead..EndRead kann beliebig parallel laufen. Um zur Frage zurückzukommen: Im Prinzip ist es egal aus welchem Threadkontext du BeginWrite..EndWrite aufrufst solange es vor bzw. nach dem Schreibvorgang passiert. Wann der passiert, sollte ein anderer Thread aber in der Regel (es gibt Ausnahmen, ja) gar nicht kontrollieren, weshalb die praktische Antwort meistens Nein ist, auch wenn es technisch egal ist. Genau lässt sich das aber nur sagen, wenn man den konkreten Ablauf kennt. Es würde auch abstrakt ohne Code genügen, z.B. auch als Diagramm, wer (Thread XY) wann (während andere Threads laufen? autark? kontrolliert durch einen anderen Thread? ...) was (Schreiben oder Lesen) macht, um einen Überblick zu haben. |
AW: Critical Section um globale Methode?
Hmm..
Der Zugriff erfolgt vergleichbar einer TCriticalSection. Beispiel:
Delphi-Quellcode:
unit Unit2;
interface uses SysUtils; function LeseDaten : string; procedure SchreibeDaten(Value : string); implementation var MSync_Global : TMultiReadExclusiveWriteSynchronizer; Daten_Test : string; function LeseDaten : string; begin MSync_Global.BeginRead; try Result := Daten_Test; finally MSync_Global.EndRead; end; end; procedure SchreibeDaten(Value : string); begin MSync_Global.BeginWrite; try Daten_Test := Value; finally MSync_Global.EndWrite; end; end; initialization MSync_Global := TMultiReadExclusiveWriteSynchronizer.Create; finalization MSync_Global.Free; end. Alle Threads (auch der Main..) nutzen nun einfach function LeseDaten : string; procedure SchreibeDaten(Value : string); für den Zugriff auf 'Daten_Test : string;'. Durch die Verwendung des globalen 'MSync_Global : TMultiReadExclusiveWriteSynchronizer;' innerhalb der Funktionen ist der Zugriff Threadsave.. ;) (Einfach nur mal so Runtergeschrieben als minimales Beispiel ;) ) (Fehler und Irtümer nicht ausgeschlossen ;) ) |
AW: Critical Section um globale Methode?
Zitat:
Delphi-Quellcode:
Wie man sieht gibt es genau eine einzige Stelle in dieser Thread-Unit, wo geschrieben wird. Alles danach ist nur noch lesen.
// Andere Unit erzeugt die Threads aus dem Mainthread heraus
erzeuge Thread 1+2+3 und gebe jedem ein Teil aus einer großen Liste; // (ja ich weiß, es gibt TParallel.For :P ) // Die Thread-unit selber -thread-instanzen 1+2+3 (alle selber Code, nur unterschiedliche Listen sind abzuarbeiten) begin schleife anfang _globals.aMultiReadExclusiveWriteSynchronizer.BeginWrite; setze globale Klasseninstanz := Liste.Items[i] _globals.aMultiReadExclusiveWriteSynchronizer.EndWrite; (a) ... lese hier ... lese dort ... lese nochmals hier (b) schleife ende end; |
AW: Critical Section um globale Methode?
Zitat:
Um das Sync zu machen, musst du dennoch von jedem Lesen 'BeginRead' und danach 'EndRead' machen! Nur fürs Schreiben BeginWrite/EndWrite reicht nicht! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:41 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