2010-01-22 5 views

Antwort

46

lock ermöglicht nur ein Thread den Code zur gleichen Zeit auszuführen. ReaderWriterLock kann ermöglichen, dass mehrere Threads gleichzeitig lesen oder exklusiven Schreibzugriff haben, daher könnte es effizienter sein. Wenn Sie .NET 3.5 verwenden, ist ReaderWriterLockSlim noch schneller. Also, wenn Ihr gemeinsam genutzte Ressource als wobei lesen öfter wird, verwenden ReaderWriterLockSlim. Ein gutes Beispiel für die Verwendung ist eine Datei, die Sie sehr oft lesen (bei jeder Anfrage) und Sie aktualisieren den Inhalt der Datei selten. Also, wenn Sie aus der Datei lesen geben Sie eine Lesesperre, so dass viele Anfragen es zum Lesen öffnen können, und wenn Sie sich entscheiden, zu schreiben, geben Sie eine Schreibsperre. Wenn Sie einen lock für die Datei verwenden, bedeutet dies grundsätzlich, dass Sie jeweils eine Anfrage gleichzeitig bearbeiten können. Betrachten

+1

also, was Sie sagen, ist, wenn der erste Thread liest einen Wert, der innerhalb der Sperre {} kein anderer Thread kann es in der gleichen Zeit lesen? – kenny

+0

Genau, 'lock' lässt nur einen Thread den Körper der Lock-Anweisung ausführen. –

+3

"so könnte es effizienter sein": aber wahrscheinlich nicht und Ihr Code wird komplexer sein. Es sollte für Nischenfälle reserviert sein. – Richard

15

ReaderWriterLock verwenden, wenn Sie viele Threads, die nur müssen die Daten und diese Threads lesen sind immer für das Schloss blockiert warten und, und Sie brauchen nicht oft die Daten zu ändern.

Allerdings kann ReaderWriterLock einen Thread blockieren, der auf das Schreiben für eine lange Zeit wartet.

daher nur ReaderWriterLock verwenden, nachdem Sie Sie hohe Konkurrenz in „ wirklichen Leben“ für die Sperre erhalten bestätigt haben, und Sie haben bestätigt, Sie nicht Ihre Schließanlage Design reduzieren, wie lange die Sperre neu gestalten kann, ist gehalten für.

Denken Sie auch darüber nach, ob Sie die geteilten Daten nicht lieber in einer Datenbank speichern und sich um die Sperrung kümmern können, da dies Ihnen die Suche nach Fehlern erschwert, wenn eine Datenbank vorhanden ist schnell genug für Ihre Anwendung.

In einigen Fällen können Sie möglicherweise auch den Aps.net-Cache verwenden, um gemeinsam genutzte Daten zu behandeln, und entfernen Sie das Element aus dem Cache, wenn sich die Daten ändern. Der nächste Lesevorgang kann eine neue Kopie in den Cache stellen.

Denken Sie daran,

„Die beste Art der Verriegelung ist die Sperren Sie nicht brauchen (das heißt nicht Austausch von Daten zwischen Threads).“

8

-Monitor und der darunter liegende „Synchronisationsblock“, der mit jedem Referenzobjekt — der zugrunde liegende Mechanismus unter C# 's lock — Unterstützung exklusive Ausführung zugeordnet werden kann. Nur ein Thread kann die Sperre haben. Dies ist einfach und effizient.

ReaderWriterLock (oder, in V3.5, die bessere ReaderWriterLockSlim) bieten ein komplexeres Modell. Vermeiden Sie, es sei denn, Sie wissen es wird effizienter (d. H. Leistungsmessungen haben, um sich selbst zu unterstützen).

Die beste Art der Sperrung ist die Sperrung, die Sie nicht benötigen (d. H. Keine Daten zwischen Threads teilen).

+4

+1 für "Die beste Art der Sperrung ist die Sperrung, die Sie nicht benötigen (d. H. Keine Daten zwischen Threads teilen)." –

4

ReaderWriterLock können Sie mehrere Threads gleichzeitig ReadLock haben ...damit Ihre gemeinsamen Daten von vielen Threads gleichzeitig konsumiert werden können. Sobald ein WriteLock angefordert wird, werden keine ReadLocks mehr gewährt und der auf WriteLock wartende Code wird blockiert, bis alle Threads mit ReadLocks diese freigegeben haben.

Die WriteLock kann immer nur von einem Thread gehalten werden, erlauben Sie Ihre "Datenaktualisierungen" aus der Sicht der verbrauchenden Teile Ihres Codes atomare erscheinen.

Die Sperre andererseits erlaubt nur einen Thread zu einem Zeitpunkt einzugeben, ohne Threads zu berücksichtigen, die einfach versuchen, die geteilten Daten zu verbrauchen.

ReaderWriterLockSlim ist eine neue leistungsfähigere Version von ReaderWriterLock mit besserer Unterstützung für Rekursion und die Fähigkeit, einen Thread bewegt von einem Verschluss zu haben, die im Wesentlichen eine ReadLock zum WriteLock ist glatt (UpgradeableReadLock).

1

Ich würde vorschlagen, obwohl http://www.albahari.com/threading/ - Teil drei spricht über ReaderWriterLockSlim (die Sie anstelle von ReaderWriterLock verwenden möchten).

6

ReaderWriterLock/Slim wurde speziell entwickelt, um Ihnen zu helfen, ein Szenario mit mehreren Konsumenten/Einzelproduzenten effizient zu sperren. Dies ist mit der Lock-Anweisung möglich, aber nicht effizient. RWL/S bekommt die Oberhand, indem es in der Lage ist, aggressiv Spinlock, um das Schloss zu erwerben. Das hilft Ihnen auch, Konvois zu vermeiden, ein Problem mit der lock-Anweisung, bei der ein Thread seine Thread-Quantum abgibt, wenn er die Sperre nicht erhalten kann, wodurch er zurückfällt, weil er für eine Weile nicht neu geplant wird.

2

Es ist wahr, dass ReaderWriterLockSlim SCHNELLER als ReaderWriterLock ist. Aber der Speicherverbrauch von ReaderWriterLockSlim ist geradezu ungeheuerlich. Versuchen Sie, einen Speicherprofiler anzubringen und sehen Sie selbst. Ich würde ReaderWriterLock jeden Tag über ReaderWriterLockSlim wählen.