Question boost scoped_lock vs plain lock / unlock


Je vais utiliser boost::mutex de boost/thread/mutex.hpp. Il existe plusieurs façons de verrouiller / déverrouiller un mutex: avec scoped_lock, unique_lock, lock_guard, fonctions membres de mutex ::lock() et ::unlock() et fonctions non membres lock() et unlock().

J'ai remarqué que boost::scoped_mutex est l'un des moyens les plus populaires d'utiliser le 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()

est scoped_lock mieux juste à cause d'un point de vue de codage de style ou est ::lock()/::unlock() pas "thread suffisamment en sécurité"?


37
2018-03-02 21:18


origine


Réponses:


Pourquoi est-il préférable d’avoir des fonctions membres :: lock () et :: unlock ()?

Pour la même raison que le Idiome RAII est devenu populaire en général (ce n’est là qu’un exemple parmi tant d’autres): parce que vous pouvez être sûr de ne pas quitter la portée actuelle sans déverrouiller le mutex.

Notez que cela ne concerne pas seulement oubli 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'en avez pas return déclaration 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 scoped_lock garde sera invoqué pendant le déroulement de la pile, en s'assurant que le mutex associé toujours se libère.

{
    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 à appeler unlock() avant chaque return déclaration.


63
2018-03-02 21:21



vous pouvez utiliser

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

si vous ne voulez pas utiliser la bibliothèque boost.


2
2018-04-26 14:21