O C ++ 17 introduziu uma nova classe de bloqueio chamada std::scoped_lock
.
A julgar pela documentação, ela se parece com a std::lock_guard
classe já existente .
Qual é a diferença e quando devo usá-la?
c++
multithreading
locking
c++17
Stephan Dollberg
fonte
fonte
lock_guard
. Mas certamente torna as classes de guarda um pouco mais fáceis de usar.A diferença única e importante é que
std::scoped_lock
um construtor variadico recebe mais de um mutex. Isso permite bloquear vários mutexes em um impasse, evitando como sestd::lock
fossem usados.Anteriormente, você tinha que dançar um pouco para bloquear vários mutexes de uma maneira segura, usando a
std::lock
explicação desta resposta .A adição do bloqueio de escopo facilita o uso e evita os erros relacionados. Você pode considerar
std::lock_guard
obsoleto. O caso de argumento único destd::scoped_lock
pode ser implementado como uma especialização e você não precisa se preocupar com possíveis problemas de desempenho.O GCC 7 já tem suporte para o
std::scoped_lock
qual pode ser visto aqui .Para obter mais informações, leia o documento padrão.
fonte
scoped_lock lk; // locks all mutexes in scope
. LGTM.scoped_lock lk;
é o novo atalho parascoped_lock<> lk;
. Não são há semáforos. Então você está certo. ;-)Resposta tardia e principalmente em resposta a:
No caso comum de que é necessário bloquear exatamente um mutex,
std::lock_guard
existe uma API um pouco mais segura de usar do quescoped_lock
.Por exemplo:
O trecho de código acima provavelmente é um erro acidental em tempo de execução porque ele compila e, em seguida, não faz absolutamente nada. O codificador provavelmente significava:
Agora ele bloqueia / desbloqueia
mut
.Se
lock_guard
foi usado nos dois exemplos acima, o primeiro exemplo é um erro em tempo de compilação em vez de um erro em tempo de execução, e o segundo exemplo tem funcionalidade idêntica à versão usadascoped_lock
.Portanto, meu conselho é usar a ferramenta mais simples para o trabalho:
lock_guard
se você precisar bloquear exatamente 1 mutex para um escopo inteiro.scoped_lock
se você precisar bloquear um número de mutexes que não sejam exatamente 1.unique_lock
se você precisar desbloquear dentro do escopo do bloco (que inclui o uso de acondition_variable
).Este conselho é que não implica que
scoped_lock
deve ser redesenhado para não aceitar 0 semáforos. Existem casos de uso válidos nos quais é desejávelscoped_lock
aceitar pacotes de parâmetros de modelos variados que possam estar vazios. E a caixa vazia não deve bloquear nada.E é por isso que
lock_guard
não é preterido.scoped_lock
eunique_lock
pode ser um superconjunto de funcionalidades delock_guard
, mas esse fato é uma faca de dois gumes. Às vezes, é tão importante o que um tipo não fará (construção padrão neste caso).fonte
Aqui está um exemplo e uma citação de C ++ Concurrency in Action :
vs.
fonte