A diferença é que você pode bloquear e desbloquear a std::unique_lock
. std::lock_guard
será bloqueado apenas uma vez na construção e desbloqueado na destruição.
Portanto, para o caso de uso B, você definitivamente precisa de um std::unique_lock
para a variável de condição. No caso A, depende se você precisa trancar a proteção novamente.
std::unique_lock
possui outros recursos que permitem, por exemplo: ser construído sem bloquear o mutex imediatamente, mas criar o wrapper RAII (veja aqui ).
std::lock_guard
também fornece um invólucro RAII conveniente, mas não pode bloquear vários mutexes com segurança. Pode ser usado quando você precisar de um wrapper para um escopo limitado, por exemplo: uma função de membro:
class MyClass{
std::mutex my_mutex;
void member_foo() {
std::lock_guard<mutex_type> lock(this->my_mutex);
/*
block of code which needs mutual exclusion (e.g. open the same
file in multiple threads).
*/
//mutex is automatically released when lock goes out of scope
};
Para esclarecer uma pergunta por chmike, por padrão std::lock_guard
e std::unique_lock
são os mesmos. Portanto, no caso acima, você pode substituir std::lock_guard
por std::unique_lock
. No entanto, std::unique_lock
pode ter um pouco mais de sobrecarga.
Note que hoje em dia deve-se usar em std::scoped_lock
vez de std::lock_guard
.