A diferença é que você pode bloquear e desbloquear a std::unique_lock. std::lock_guardserá 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_lockpara a variável de condição. No caso A, depende se você precisa trancar a proteção novamente.
std::unique_lockpossui outros recursos que permitem, por exemplo: ser construído sem bloquear o mutex imediatamente, mas criar o wrapper RAII (veja aqui ).
std::lock_guardtambé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_guarde std::unique_locksão os mesmos. Portanto, no caso acima, você pode substituir std::lock_guardpor std::unique_lock. No entanto, std::unique_lockpode ter um pouco mais de sobrecarga.
Note que hoje em dia deve-se usar em std::scoped_lockvez de std::lock_guard.