Konzept von Lese-/Schreibsperren in C++

Muhammad Adil 16 Februar 2024
  1. Zweck und Verwendung von Lese-/Schreibsperren
  2. Schritte zum Implementieren von Lese-/Schreibsperren in C++
Konzept von Lese-/Schreibsperren in C++

Eine Lese-/Schreibsperre ist ein Synchronisierungsmechanismus, der es Threads ermöglicht, die Sperre zum Lesen oder Schreiben zu erwerben, sodass ein Thread einen anderen nicht daran hindert, auf die Ressource zuzugreifen, während sie geändert wird.

Sie werden häufig verwendet, um schreibgeschützte gemeinsam genutzte Datenstrukturen zu implementieren, z. B. einen globalen Cache oder eine Lookup-Tabelle. Die Lese-/Schreibsperre kann entweder unter Verwendung von Bedingungsvariablen oder Mutexes implementiert werden.

Zweck und Verwendung von Lese-/Schreibsperren

Lesersperren werden verwendet, wenn der Leser die Daten nicht ändern kann. Die Writer-Sperre wird verwendet, wenn ein Writer exklusiven Zugriff zum Ändern von Daten wünscht.

Lesesperren werden auch als “Nur-Lese”-Sperren bezeichnet und sind häufig in Mehrbenutzersystemen zu finden. Sie ermöglichen einem oder mehreren Lesern den Zugriff auf die Daten, ohne diese zu beeinträchtigen, während ein Schreiber die Daten nur ändern kann, wenn er exklusiven Zugriff darauf hat.

Auf der anderen Seite werden Schreibsperren verwendet, wenn nur eine Person gleichzeitig Änderungen in eine Datei schreiben können muss. Dies verhindert gleichzeitiges Schreiben und stellt sicher, dass keine Konflikte zwischen Aktualisierungen auftreten, die von verschiedenen Personen zu unterschiedlichen Zeiten vorgenommen wurden.

Schritte zum Implementieren von Lese-/Schreibsperren in C++

In C++ können Lese-/Schreibsperren in wenigen Schritten implementiert werden.

  1. Zunächst muss die Sperre mit einem shared_ptr auf die durch die Sperre geschützte Ressource initialisiert werden.
  2. Zweitens muss eine Funktion erstellt werden, um die Sperre bei Bedarf zu erwerben und freizugeben.
  3. Drittens müssen die Funktionen acquire und release zu geeigneten Zeiten aufgerufen werden.
  4. Viertens muss eine Funktion erstellt werden, die prüft, ob andere Threads auf dieselbe Ressource warten, die sie bereits hält, und falls ja, wartet, bis sie sie freigegeben hat, bevor sie sie erneut anfordert.
  5. Rufen Sie fünftens diese Funktion aus den Funktionen acquire und release aus Schritt zwei auf.

Beispiel:

#include <iostream>
#include <mutex>
#include <shared_mutex>
#include <thread>

using namespace std;

class demo {
 public:
  void sam() {
    unique_lock lock(mutex_);
    ++b;
  }

  unsigned int get() {
    shared_lock lock(mutex_);
    return b;
  }

 private:
  mutable shared_mutex mutex_;
  unsigned int b = 0;
};

int main() {
  demo tbh;

  auto sam_and_roi = [&tbh]() {
    for (int x = 0; x < 6; x++) {
      tbh.sam();
      cout << this_thread::get_id() << tbh.get() << '\n';
    }
  };

  thread start(sam_and_roi);
  start.join();
}

Klicken Sie hier, um die Funktionsweise des Beispiels wie oben erwähnt zu überprüfen.

Muhammad Adil avatar Muhammad Adil avatar

Muhammad Adil is a seasoned programmer and writer who has experience in various fields. He has been programming for over 5 years and have always loved the thrill of solving complex problems. He has skilled in PHP, Python, C++, Java, JavaScript, Ruby on Rails, AngularJS, ReactJS, HTML5 and CSS3. He enjoys putting his experience and knowledge into words.

Facebook