7 Stimmen

.NET ReaderWriterLockSlim Probleme

Es wird viel über die Klasse ReaderWriterLockSlim geschrieben, die mehrfaches Lesen und einmaliges Schreiben ermöglicht. Alle (zumindest die, die ich gefunden habe) sagen, wie man sie benutzt, ohne viel Erklärung, warum und wie sie funktioniert. Das Standard-Codebeispiel ist:

lock.EnterUpgradeableReadLock();

try
{
   if (test if write is required)
   {
      lock.EnterWriteLock();

      try
      {
          change the resourse here.
      }
      finally
      {
         lock.ExitWriteLock();
      }
   }
}
finally
{
   lock.ExitUpgradeableReadLock();
}

Die Frage ist: Wenn die aufrüstbare Sperre nur einem einzigen Thread erlaubt, ihren Bereich zu betreten, warum sollte ich dann die Methode EnterWriteLock darin aufrufen? Was wird passieren, wenn ich das nicht tue? Oder was passiert, wenn ich anstelle von EnterUpgradeableReadLock EnterWriteLock aufrufe und in eine Ressource schreibe, ohne die aufrüstbare Sperre überhaupt zu verwenden?

10voto

Fredrik Mörk Punkte 151006

Der Vorteil der Verwendung von EnterUpgradeableReadLock über EnterReadLock ist, dass Sie sicher sein können, dass sich die Bedingung, die Sie prüfen, um zu entscheiden, ob die Schreibsperre aktiviert werden soll oder nicht, zwischen der Prüfung der Bedingung und der tatsächlichen Aktivierung der Schreibsperre nicht ändert. Dadurch wird die Duplizierung vermieden, die bei regulären lock s:

if (whatever-condition)
{
    lock (_lockObject)
    {
        // the condition may have changed betwen the check and the lock; verify
        // that the condition is still valid
        if (whatever-condition)
        {
            // do the stuff
        }
    }
}

Gleichzeitig ist es aber auch pas blockieren Aufrufe an EnterReadLock so dass andere Threads immer noch Lesezugriff in anderen Teilen des Codes erhalten können (und diese Aufrufe werden natürlich den Aufruf von EnterWriteLock bis sie die Lesesperren freigeben).

0 Stimmen

Vielen Dank an alle! Da ich eine einzige Antwort akzeptieren kann, habe ich (subjektiv) diese als die informativste ausgewählt.

4voto

Jeff Sternal Punkte 46528

wenn das aufrüstbare Schloss nur eine nur einen einzigen Thread in seinen Bereich eintreten lässt, warum sollte ich die Methode EnterWriteLock Methode aufrufen?

EnterWriteLock würde andere Threads blockieren, die nur lesen müssen - wenn Sie eine erweiterbare Sperre verwenden, können andere Threads immer noch Lesesperren erhalten. Von der EnterUpgradableLock Dokumentation:

Nur ein Thread kann upgradefähig eingegeben werden Modus zu einem bestimmten Zeitpunkt wechseln. Wenn sich ein Thread im aktualisierbaren Modus, und es gibt keine Threads warten, um in den Schreibmodus zu gelangen, eine beliebige Anzahl von anderen Threads eintreten kann Lesemodus eintreten, auch wenn es Threads gibt warten, um in den aktualisierbaren Modus zu gelangen.

0 Stimmen

Blockiert EnterUpgradeableReadLock nicht auch alle Threads, bis es beendet wird?

0 Stimmen

Nein, ich werde meine Antwort mit dem entsprechenden Teil der Dokumentation aktualisieren.

1voto

Chris Punkte 25589

Die Klasse ReaderWriterLockSlim umhüllt im Wesentlichen die Schreibsperre und erlaubt allen Lesern zu lesen, solange die Schreibsperre nicht gehalten wird. Sobald die Schreibsperre gehalten wird, können keine Leser mehr lesen.

Die Idee hinter EnterUpgradeableReadLock ist einfach, dem Programmierer die Möglichkeit zu geben, seine Absicht explizit anzugeben und nicht versehentlich etwas zu verändern.

pm100 - es ist schneller, weil eine Sperre nicht exklusiv ist, da viele Threads gleichzeitig lesen können, was leseintensive Anwendungen beschleunigen kann. Wenn Ihre Anwendung sehr schreibintensiv ist, ist dies möglicherweise nicht die beste Lösung für Sie. Dies funktioniert am besten, wenn selten Änderungen vorgenommen werden, aber viele Lesevorgänge erforderlich sind.

0 Stimmen

Sie sagen, dass das EnterUpgradeableReadLock nur der Eindeutigkeit dient und theoretisch durch EnterWriteLock ersetzt werden kann?

0 Stimmen

Innerlich. Wenn Sie nur EnterWriteLock verwenden, werden alle Leser blockiert, so dass dies nicht sinnvoll ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X