Der Unterschied besteht darin, dass Sie ein std::unique_lock
sperren und entsperren können. std::lock_guard
wird nur einmal während der Konstruktion gesperrt und bei der Zerstörung entsperrt.
Also für Anwendungsfall B benötigen Sie definitiv einen std::unique_lock
für die Bedingungsvariable. Im Fall von A hängt es davon ab, ob Sie den Wächter erneut sperren müssen.
std::unique_lock
hat weitere Funktionen, die es z. B. ermöglichen, ihn ohne sofortiges Sperren des Mutex zu erstellen, aber den RAII-Wrapper zu erstellen (siehe hier).
std::lock_guard
bietet auch einen bequemen RAII-Wrapper, kann jedoch nicht mehrere Mutexe sicher sperren. Es kann verwendet werden, wenn Sie einen Wrapper für einen begrenzten Bereich benötigen, z. B.: eine Member-Funktion:
class MyClass{
std::mutex my_mutex;
void member_foo() {
std::lock_guard lock(this->my_mutex);
/*
Codeblock, der gegenseitigen Ausschluss benötigt (z. B. öffnen der
gleichen Datei in mehreren Threads).
*/
// Der Mutex wird automatisch freigegeben, wenn der Sperre aus dem Gültigkeitsbereich geht
}
};
Um eine Frage von chmike zu klären, sind standardmäßig std::lock_guard
und std::unique_lock
gleich. Also in dem obigen Fall könnten Sie std::lock_guard
durch std::unique_lock
ersetzen. Allerdings hat std::unique_lock
möglicherweise etwas mehr Overhead.
Beachten Sie, dass heutzutage (seit C++17) man anstelle von std::lock_guard
std::scoped_lock
verwenden sollte.