Je vais utiliser boost::mutex
De boost/thread/mutex.hpp
. Il existe plusieurs façons de verrouiller/déverrouiller mutex: avec scoped_lock
, unique_lock
, lock_guard
, Les fonctions membres de mutex ::lock()
et ::unlock()
et les fonctions non membres lock()
et unlock()
.
J'ai remarqué que boost::scoped_mutex
Est l'une des façons les plus populaires d'utiliser mutex. Pourquoi est-il préférable aux fonctions membres ::lock()
et ::unlock()
?
En particulier, pourquoi devrais-je utiliser
{
boost::scoped_lock lock(mutex)
// ...
// read/output sharing memory.
// ...
}
plutôt que
mutex.lock()
// ...
// read/output sharing memory.
// ...
mutex.unlock()
scoped_lock
est-il préférable simplement à cause d'un point de vue de codage de style ou ::lock()/::unlock()
n'est-il pas "assez sûr pour les threads"?
Pourquoi est-il préférable aux fonctions membres :: lock () et :: unlock ()?
Pour la même raison pour laquelle le idiome RAII est devenu populaire en général (ce n'est qu'une de ses innombrables instances): parce que vous pouvez être sûr de ne pas quitter la portée actuelle sans déverrouiller le mutex.
Remarquez qu'il ne s'agit pas seulement d'oublier d'appeler unlock()
: une exception peut se produire lorsque votre mutex est verrouillé et votre appel à unlock()
peut ne jamais être atteint, même si vous n'avez aucune instruction return
entre votre appel à lock()
et votre appel à unlock()
.
m.lock() // m is a mutex
// ...
foo(); // If this throws, your mutex won't get unlocked
// ...
m.unlock()
Dans ce cas, le destructeur de votre garde scoped_lock
Sera invoqué pendant le déroulement de la pile, en s'assurant que le mutex associé toujours est libéré.
{
boost::scoped_lock lock(m); // m is a mutex
// ...
foo(); // If this throws, your RAII wrapper will unlock the mutex
// ...
}
De plus, dans de nombreuses situations, cela améliorera la lisibilité de votre code, dans la mesure où vous n'aurez pas à ajouter d'appel à unlock()
avant chaque instruction return
.
vous pouvez utiliser
std::lock_guard<std::mutex> lock(mutex);
si vous ne voulez pas utiliser la bibliothèque boost.