Parallelzugriff auf Daten

Teil 4: Programmieren für Multi-Core-Prozessoren

ReaderWriterLockSlim und ReaderWriterLock

ReaderWriterLock beanspruchte viele Ressourcen und CPU-Laufzeit. Daher stellt .Net 3.5 nun die Klasse ReaderWriterLockSlim bereit. ReaderWriterLockSlim ist bedeutend schneller und geht schonender mit den Ressourcen um.

Beide Klassen jeweils zwei Lock-Operationen bereit: Eine Sperre für Leseoperationen und eine Sperre für Schreiboperationen. Schreibsperren sind im Allgemeinen exklusiv, Lesesperren in der Regel jedoch nicht. Diese können folglich immer parallel existieren.

Ein Thread, der eine Schreibsperre besitzt, blockiert damit alle weiteren Lese- und Schreibsperren. Dies soll verhindern, dass ein anderer Thread auf veralteten Daten operiert, die mittlerweile durch den Schreibzugriff verändert wurden. Hinzu kommt, dass aus Performance-Gründen die gelesenen Daten häufig intern, im Kontext der Threads, gepuffert werden. Wird nun parallel durch einen schreibenden Zugriff von Thread_A das Datum verändert, bevor der Thread_B das Datum intern verarbeitet, so operiert Thread_B auf alten Inhalten.

Der folgende skizzierte Ablauf soll dies verdeutlichen:

  • Thread_A liest das Datum_A und erhält den Wert_X zurück und puffert ihn im Thread

  • Thread_B liest das Datum_A und erhält den Wert_X zurück und puffert ihn im Thread

  • Thread_A ändert das Datum_A auf Wert_Y

  • Thread_B operiert nun auf den alten Inhalten (Wert_X) von Datum_A

Aber es gilt auch in umgekehrter Richtung. Ein Thread, der eine Lesesperre besitz, blockiert alle anderen Threads, die ein Schreibsperre anfordern. Daher verlangt ReaderWriterLock die Freigabe zum Schreiben von allen lesenden Objekten.

ReaderWriterLockSlim umfasst die folgenden Methoden zur Verwaltung der Schreib-/Lesesperren:

  • EnterReadLock();

  • ExitReadLock();

  • EnterWriteLock();

  • ExitWriteLock();