Frage

Eine weitere Synchronisation Frage ... Ich hoffe, ihr nicht bekommen verärgert;)

Nehmen wir das folgende Szenario: eine zentrale Strukturdaten (. Sehr groß, so will ich nicht wirklich, um es unveränderlich machen und kopieren Sie sie um, wenn eine Änderung auftritt, ich selbst will nicht mehrere Kopien im Speicher halten), mehrere Leser-Threads, der Zugriff auf die Datenstruktur, schreibgeschützt und einen Schreiber-Thread, der die Datenstruktur auf dem aktuellen Stand im Hintergrund hält.

ich synchronisieren derzeit alle auf die Datenstruktur zugreift, die einfach gut (keine Synchronisation Effekte, keine Deadlocks) funktioniert. Was ich nicht über diesen Ansatz gefällt ist, dass die meiste Zeit habe ich viel Leser haben Threads aktiv und der Schriftsteller Faden ab und zu nur aktiv. Nun ist es völlig unnötig für die Leser-Threads für andere Leser-Threads warten zu beenden. Sie könnten leicht die Datenstruktur parallel zugreifen, solange der Writer-Thread derzeit nicht schreibt.

Gibt es eine schöne und elegante Art und Weise, diese Art von Szenario zu lösen?

EDIT: Vielen Dank für die Antworten und Links! Lassen Sie mich nur noch eine kurze und damit verbundene Frage hinzu: wenn der Code innerhalb des Lesers kritischer Abschnitte ausgeführt dauert nur eine sehr kurze Zeit (wie nur eine Hash-Lookup-Tabelle), ist es auch eine Überlegung wert, eine der Techniken, die Umsetzung Sie beschreiben oder die Serialisierung Wirkung der Sperren nicht so schlecht in diesem Fall? Skalierbarkeit und Leistung sind sehr wichtig. Was denken Sie?

EDIT 2: Ich sehe nur in eine Implementierung eines einzelnen Autor / mulitple Leser - Sperre und diese Implementierung verwendet einen Monitor einige Codes in der WaitToRead Methode zu synchronisieren. Ist dies nicht dazu führen, die gleiche Serialisierung Effekt, dass ich in erster Linie vermeiden wollte? (Noch unter der Annahme, dass der Code synchronisiert werden soll, kurz und schnell)

War es hilfreich?

Lösung

Es gibt eine Klasse für diesen Zweck in RTL (sysutils): TMultiReadExclusiveWriteSynchroniser

Es ist sehr einfach zu bedienen. Sie müssen nicht unbedingt auf Ihre Themen wie Leser oder Schreiber kategorisieren. Rufen Sie „Beginread“ oder „Beginwrite“ in ein Gewinde ein Gewinde für einen sicheren Betrieb zu starten. Call "EndRead" oder "EndWrite" für den Betrieb beenden.

Andere Tipps

Was Sie suchen (und welche vartec beschrieben) aufgerufen Reader (n) -Writer -Lock .

Sie können einige detaillierte Hinweise zur Lösung dieses Problems unter Msdn Magazin und ein Auszug aus Programmieranwendungen für MS Windows .

ein Reader-Writer Schloss wird das Problem lösen. Mehrere Leser können auf eine Datenbank zugreifen und ein Autor bekommt eine Sperre, wenn alle Leser das Lesen fertig sind.

Allerdings könnte dies bewirken, dass der Schriftsteller nie Zugriff auf die Quelle hat, da es immer neue Leser sind, den Zugang will. Dies kann durch die Blockierung neue Leser gelöst werden, wenn ein Schriftsteller Zugang will: der Schriftsteller hat eine größere Priorität. Der Autor erhält Zugriff, wenn alle Leser auf die Quelle zu lesen sind fertig.

Wenn Schriftsteller zugreifen möchte, Sie enqueue eingehende Leser (haben sie auf Zustand warten), für die aktiven Leser warten zu beenden, schreiben und wenn der Zugang lassen die Warteschlange eingereiht Leser beendet.

Niemand kann wirklich Ihre Frage beantworten, ob die Serialisierung Leistung in Ihrer Anwendung auswirken wird sehr viel -. Sie, dass für sich selbst profilieren haben, und die Ergebnisse werden stark von der Anzahl der Threads, die Kerne und der spezifischen Arbeitsbelastung abhängig

Beachten Sie jedoch, dass schlauer Synchronisation als kritische Abschnitte, wie die Leser-Schreiber-Sperre verwendet wird, einführen kann Hunger Probleme, die schwer zu debuggen und fix sein kann. Sie müssen wirklich hart an, ob die erhöhten Durchsatz überwiegt die möglichen Probleme zu suchen. Beachten Sie auch, dass es nicht wirklich eine Durchsatzsteigerung sein kann, vor allem, wenn der gesperrte Code sehr kurz und schnell. Es gibt einen schöne Artikel von Jeffrey Richter dass tatsächlich dieses Zitat enthält:

  

Performance Auch wenn es keine Konkurrenz für eine ReaderWriterLock ist, seine Leistung ist sehr langsam. Zum Beispiel nimmt ein Aufruf an seine AcquireReaderLock Methode etwa fünfmal länger auszuführen als ein Anruf des zur Überwachung Methode eingeben.

Dies ist für .NET natürlich, aber die zugrunde liegenden Prinzipien auch gelten.

Die Leser-Schreiber-Sperre ist, was Sie brauchen. Tutorial hat eine Beschreibung, aber ich bin sicher, dass jemand das Hinzufügen dieser als Standard zu Delphi. Kann D2009 lohnen Überprüfung nicht über es bereits.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top