Ich lerne C ++ und habe gesehen, dass der Quellcode für eine Bereichssperre ziemlich einfach ist. . Wie funktioniert es, und wie ist dies ein Beispiel für "Ressourcenbeschaffung ist Instanziierung" (RAII)?
Die Idee von RAII (Resource Acquisition Is Initialization) ist, dass das Erstellen und Initialisieren eines Objekts zu einer untrennbaren Aktion zusammengefügt wird. Dies bedeutet im Allgemeinen, dass sie im Konstruktor des Objekts ausgeführt werden.
Begrenzte Sperren funktionieren, indem sie einen Mutex beim Erstellen sperren und ihn entsperren, wenn sie zerstört werden. Die C ++ - Regeln garantieren, dass, wenn der Kontrollfluss einen Bereich verlässt (sogar über eine Ausnahme), Objekte, die für den zu exportierenden Bereich lokal sind, korrekt zerstört werden. Dies bedeutet, dass die Verwendung einer Bereichssperre anstelle des manuellen Aufrufs von lock()
und unlock()
es unmöglich macht, den Mutex versehentlich nicht zu entsperren, z. wenn eine Ausnahme in die Mitte des Codes zwischen lock()
und unlock()
geworfen wird.
Dieser Grundsatz gilt für alle Szenarios zum Erwerb von Ressourcen, die freigegeben werden müssen, nicht nur zum Sperren von Mutexen. Es empfiehlt sich, solche "scope guard" -Klassen für andere Operationen mit ähnlicher Syntax bereitzustellen.
Ich habe zum Beispiel kürzlich an einer Datenstrukturklasse gearbeitet, die normalerweise Signale sendet, wenn sie geändert wird, aber diese müssen für einige Massenoperationen deaktiviert werden. Die Bereitstellung einer Schutzklasse für den Schutzbereich, die sie bei der Erstellung deaktiviert und sie bei der Zerstörung wieder freigibt, verhindert mögliche unsymmetrische Aufrufe der Funktionen zum Deaktivieren / Aktivieren.
Grundsätzlich funktioniert das so:
%Vor%Wenn Sie es wie
verwenden %Vor% Sie erstellen ein neues Objekt mit einer bereichsbasierten Lebensdauer. Wenn der aktuelle Bereich verlassen wird und diese Sperre zerstört wird, wird automatisch mtx.unlock()
aufgerufen. Beachten Sie, dass in diesem speziellen Beispiel die Sperre für den Mutex vom Konstruktor von lock
, also RAIII, übernommen wird.
Wie würdest du das ohne einen Schutzschirm machen? Sie müssten mtx.unlock()
aufrufen, wenn Sie die Funktion verlassen. Dies ist a) umständlich und b) fehleranfällig. Außerdem können Sie den Mutex nach eine Rückgabe ohne einen Schutzbereich nicht freigeben.
Tags und Links c++