58 votes

boost :: unique_lock vs boost :: lock_guard

Je ne comprends pas bien la différence entre ces deux classes de verrous. Dans la documentation Boost, il est dit que boost::unique_lock ne réalise pas le verrouillage automatiquement.

Cela signifie-t-il que la principale différence entre unique_lock et lock_guard est qu'avec unique_lock nous devons appeler explicitement la fonction lock() ?

60voto

mkaes Points 6867

D'abord pour répondre à votre question. Non, vous n'avez pas besoin d'appeler le verrou sur un unique_lock. Voir ci-dessous:

Le unique_lock n'est qu'un verrouillage de la classe avec le plus de fonctionnalités. Dans la plupart des cas, la lock_guard à faire ce que vous voulez et ce sera suffisant.
Le unique_lock a plus de fonctionnalités à offrir à vous. E. g un temps d'attente si vous avez besoin d'un délai d'attente ou si vous souhaitez différer votre serrure à un point plus tard que la construction de l'objet. Donc ça dépend ce que vous voulez faire. BTW: Les extraits de code suivants font la même chose.

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

boost::mutex mutex;
boost::unique_lock<boost::mutex> lock(mutex);

Le premier peut être utilisé pour synchroniser l'accès aux données, mais si vous souhaitez utiliser les variables de condition, vous devez aller pour le second.

44voto

jayadev Points 982

Les meilleures voté réponse est bonne, mais il n'a pas d'éclaircir mes doutes jusqu', j'ai creusé un peu plus profond donc décidé de partager avec des personnes qui pourraient être dans le même bateau.

Tout d'abord les deux lock_guard et unique_lock suit le RAII motif, dans le plus simple des cas d'utilisation de la serrure est acquis au cours de la construction et débloqué lors de la destruction automatiquement. Si tel est votre cas, alors vous n'avez pas besoin de plus de flexibilité de unique_lock et lock_guard sera plus efficace.

La principale différence entre les deux est une unique_lock instance n'a pas besoin de toujours propre le mutex il est associé à tout dans lock_guard il possède le mutex. Cela signifie unique_lock aurait besoin d'avoir un indicateur supplémentaire indiquant s'il possède le verrou et une autre méthode supplémentaire 'owns_lock()' pour vérifier. Sachant cela, nous pouvons expliquer tous les avantages supplémentaires de ce drapeaux apporte avec le traitement de données supplémentaires et de les vérifier -

  1. Verrouillage de ne pas avoir à les prendre à droite à la construction, vous pouvez passer le drapeau std::defer_lock lors de sa construction pour garder le mutex débloqué en cours de construction.
  2. On peut le déverrouiller avant que la fonction prend fin et vous ne devez pas nécessairement attendre que destructeur pour le libérer, ce qui peut être pratique.
  3. Vous pouvez transmettre la propriété de la serrure d'une fonction, il est mobile et non copiable.
  4. Il peut être utilisé avec des variables conditionnelles depuis que nécessite mutex pour être verrouillé, l'état vérifié et déverrouillé en attente d'une condition.

14voto

Leur mise en œuvre peut être trouvé sous chemin d'accès .../boost/thread/verrous.php - et ils sont assis juste à, les uns à côté des autres :) Pour résumer les choses de court:

lock_guard est court, simple, classe utilitaire qui bloque mutex dans le constructeur et déverrouille dans le destructeur, sans se soucier des détails.

unique_lock est un peu plus complexe, en ajoutant assez grand nombre de fonctionnalités - mais il se verrouille automatiquement dans le constructeur. Il est appelé unique_lock car elle introduit la "propriété verrouillage" concept ( voir owns_lock() la méthode ).

6voto

Sean Points 4446

Si vous avez l'habitude d' pthreads(3):

  • boost::mutex = pthread_mutex_*
  • boost::unique_lock = pthread_rwlock_* utilisés pour obtenir de l'écriture/verrous exclusifs (c - pthread_rwlock_wrlock)
  • boost::shared_lock = pthread_rwlock_* utilisé pour obtenir de lecture/verrous partagés (c - pthread_rwlock_rdlock)

Oui un boost::unique_lock et boost::mutex fonction de manière similaire, mais un boost::mutex est généralement un poids plus léger mutex pour acquérir et de libération. Cela dit, shared_lock avec la serrure déjà acquis est plus rapide (et permet de simultanéité), mais c'est relativement cher pour obtenir un unique_lock.

Vous avez à regarder sous les couvertures pour voir les détails de mise en œuvre, mais c'est le sens de la destinée des différences.


Parlant de la performance: voici un modérément utile comparaison des latences:

http://www.eecs.berkeley.edu/%7Ercs/research/interactive_latency.html

Ce serait bien si j'/quelqu'un pourrait comparer le coût relatif des différents pthread_* primitives, mais le dernier que j'ai regardé, pthread_mutex_* ~25us, alors qu' pthread_rwlock_* ~20-100us selon si oui ou non le verrou en lecture avait déjà été acquis (~10us) ou non (~20us) ou de l'écrivain (~100us). Vous aurez pour indice de référence pour confirmer les chiffres et je suis sûr que c'est très spécifique au système d'exploitation.

1voto

Alex Petrenko Points 523

Je pense que unique_lock peut également être utilisé lorsque vous devez souligner la différence entre les verrous uniques et partagés.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X