/ / boost scoped_lock vs lock / unlock simples - c ++, boost, thread-safety, mutex

aumentar scoped_lock vs lock / unlock simples - c ++, boost, thread-safety, mutex

Eu vou usar boost::mutex a partir de boost/thread/mutex.hpp. Existem várias maneiras de bloquear / desbloquear mutex: com scoped_lock, unique_lock, lock_guardfunções-membro do mutex ::lock() e ::unlock() e funções não-membros lock() e unlock().

Eu percebi isso boost::scoped_mutex é uma das formas mais populares de usar o mutex. Por que é preferível às funções de membro ::lock() e ::unlock()?

Particularmente, por que devo usar

{
boost::scoped_lock lock(mutex)
// ...
// read/output sharing memory.
// ...
}

ao invés de

mutex.lock()
// ...
// read/output sharing memory.
// ...
mutex.unlock()

é scoped_lock melhor apenas por causa de algum ponto de vista de codificação de estilo ou é ::lock()/::unlock() não "fio seguro o suficiente"?

Respostas:

63 para resposta № 1

Por que é preferível a funções de membro :: lock () e :: unlock ()?

Pela mesma razão porque o Idioma RAII tornou-se popular em geral (esta é apenas uma das suas inúmeras instâncias): porque você pode ter certeza que você não "deixa o escopo atual sem desbloquear o mutex.

Note que isto não é apenas sobre esquecendo chamar unlock(): uma exceção pode ocorrer enquanto o seu mutex estiver bloqueado, e sua chamada para unlock() pode nunca ser alcançado, mesmo que você não tenha return declaração entre a sua chamada para lock() e sua chamada para unlock().

m.lock() // m is a mutex
// ...
foo(); // If this throws, your mutex won"t get unlocked
// ...
m.unlock()

Neste caso, o destruidor do seu scoped_lock guarda será invocado durante o desenrolamento da pilha, assegurando que o mutex associado sempre é liberado.

{
boost::scoped_lock lock(m); // m is a mutex
// ...
foo(); // If this throws, your RAII wrapper will unlock the mutex
// ...
}

Além disso, em muitas situações isso irá melhorar a legibilidade do seu código, pois você não terá que adicionar uma chamada para unlock() antes de cada return declaração.


2 para resposta № 2

você pode usar

std::lock_guard<std::mutex> lock(mutex);

se não quiser usar a biblioteca de reforço.