In C ++ 17 wurde eine neue Sperrklasse namens eingeführt std::scoped_lock
.
Aus der Dokumentation geht hervor, dass es der bereits vorhandenen std::lock_guard
Klasse ähnelt .
Was ist der Unterschied und wann sollte ich es verwenden?
quelle
In C ++ 17 wurde eine neue Sperrklasse namens eingeführt std::scoped_lock
.
Aus der Dokumentation geht hervor, dass es der bereits vorhandenen std::lock_guard
Klasse ähnelt .
Was ist der Unterschied und wann sollte ich es verwenden?
Dies scoped_lock
ist eine streng überlegene Version lock_guard
, die eine beliebige Anzahl von Mutexen gleichzeitig sperrt (unter Verwendung des gleichen Deadlock-Vermeidungsalgorithmus wie std::lock
). In neuem Code sollten Sie immer nur verwenden scoped_lock
.
Der einzige Grund, der lock_guard
noch besteht, ist die Kompatibilität. Es konnte nicht einfach gelöscht werden, da es im aktuellen Code verwendet wird. Darüber hinaus erwies es sich als unerwünscht, seine Definition zu ändern (von unär zu variadisch), da dies auch eine beobachtbare und damit brechende Änderung ist (jedoch aus etwas technischen Gründen).
lock_guard
. Aber es macht die Wachklassen sicherlich ein bisschen einfacher zu benutzen.Der einzige und wichtige Unterschied besteht darin, dass
std::scoped_lock
ein variadischer Konstruktor mehr als einen Mutex verwendet. Dies ermöglicht es, mehrere Mutexe in einem Deadlock zu sperren und so zu vermeiden, als obstd::lock
sie verwendet würden.Zuvor mussten Sie ein wenig tanzen, um mehrere Mutexe auf sichere Weise zu sperren, indem Sie diese Antwort
std::lock
wie erläutert verwenden .Das Hinzufügen einer Oszilloskopsperre erleichtert die Verwendung und vermeidet die damit verbundenen Fehler. Sie können als
std::lock_guard
veraltet betrachten. Der Einzelargumentfall vonstd::scoped_lock
kann als Spezialisierung implementiert werden, sodass Sie sich nicht vor möglichen Leistungsproblemen fürchten müssen.GCC 7 hat bereits Unterstützung,
std::scoped_lock
die hier zu sehen ist .Weitere Informationen finden Sie im Standardpapier
quelle
scoped_lock lk; // locks all mutexes in scope
. LGTM.scoped_lock lk;
ist die neue Abkürzung fürscoped_lock<> lk;
. Es gibt keine Mutexe. Du hast also recht. ;-)Späte Antwort und meistens als Antwort auf:
Für den allgemeinen Fall, dass man genau einen Mutex sperren muss,
std::lock_guard
gibt es eine API, die etwas sicherer zu verwenden ist alsscoped_lock
.Beispielsweise:
Das obige Snippet ist wahrscheinlich ein versehentlicher Laufzeitfehler, da es kompiliert und dann absolut nichts tut. Der Codierer meinte wahrscheinlich:
Jetzt wird es gesperrt / entsperrt
mut
.Wenn
lock_guard
stattdessen in den beiden obigen Beispielen verwendet wurde, ist das erste Beispiel ein Kompilierungsfehler anstelle eines Laufzeitfehlers, und das zweite Beispiel hat die gleiche Funktionalität wie die verwendete Versionscoped_lock
.Mein Rat ist also, das einfachste Werkzeug für den Job zu verwenden:
lock_guard
Wenn Sie genau 1 Mutex für einen gesamten Bereich sperren müssen.scoped_lock
Wenn Sie eine Anzahl von Mutexen sperren müssen, ist dies nicht genau 1.unique_lock
wenn Sie im Rahmen des Blocks entsperren müssen (einschließlich der Verwendung mit acondition_variable
).Dieser Ratschlag bedeutet nicht , dass er
scoped_lock
neu gestaltet werden sollte, um keine 0 Mutexe zu akzeptieren. Es gibt gültige Anwendungsfälle, in denen es wünschenswert istscoped_lock
, variable Vorlagenparameterpakete zu akzeptieren, die möglicherweise leer sind. Und der leere Koffer sollte nichts verriegeln.Und deshalb
lock_guard
ist es nicht veraltet.scoped_lock
undunique_lock
mag eine Obermenge der Funktionalität von seinlock_guard
, aber diese Tatsache ist ein zweischneidiges Schwert. Manchmal ist es genauso wichtig, was ein Typ nicht kann (in diesem Fall Standardkonstrukt).quelle
Hier ist ein Beispiel und ein Zitat aus C ++ Concurrency in Action :
vs.
quelle