Quelle est la différence entre un verrou exclusif et un verrou partagé?


119

Selon wikipedia,

Les verrous partagés sont parfois appelés «verrous de lecture» et les verrous exclusifs sont parfois appelés «verrous d'écriture».

Pouvez-vous expliquer le raisonnement derrière les termes «partagé» et «exclusif»?


Le verrou non exclusif est-il un autre nom de verrou partagé?
Ramesh Papaganti

Réponses:


419

J'ai écrit cette réponse parce que je pensais que ce serait une analogie amusante (et appropriée):

Pensez à un objet verrouillable comme un tableau noir (verrouillable) dans une salle de classe contenant un enseignant (écrivain) et de nombreux étudiants (lecteurs).

Pendant qu'un enseignant écrit quelque chose (verrou exclusif) sur le tableau:

  1. Personne ne peut le lire, car il est toujours en cours d'écriture, et elle bloque votre vue => Si un objet est exclusivement verrouillé, les verrous partagés ne peuvent pas être obtenus .

  2. Les autres enseignants ne viendront pas et ne commenceront pas à écrire non plus, ou le tableau devient illisible et déroute les élèves => Si un objet est exclusivement verrouillé, d'autres verrous exclusifs ne peuvent pas être obtenus .

Lorsque les élèves lisent (verrous partagés) ce qu'il y a sur le tableau:

  1. Ils peuvent tous lire ce qu'il contient, ensemble => Plusieurs verrous partagés peuvent coexister .

  2. L'enseignant attend qu'ils aient fini de lire avant de libérer le tableau pour en écrire plus => Si un ou plusieurs verrous partagés existent déjà, les verrous exclusifs ne peuvent pas être obtenus .


2
très bonne explication. Cependant, l'OP a demandé l' origine des dénominations «partagées» et «exclusives», et non une explication des thermes en soi.
serhio

Est-ce "Si un ou plusieurs verrous partagés existent déjà, les verrous exclusifs ne peuvent pas être obtenus." est vrai? Interms de ReentrantReadWriteLock? Je pensais que le verrouillage en écriture pouvait être obtenu à tout moment, sinon un manque d'écriture pourrait survenir en raison de la lecture continue.
Kanagavelu Sugumar

1
@KanagaveluSugumar, oui, c'est vrai. Vous ne pouvez tout simplement pas obtenir un verrou en écriture lorsqu'une autre entité détient déjà un verrou en lecture sur le même objet. C'est tout l'intérêt d'un verrou en lecture-écriture. Si vous écrasez quelque chose pendant que quelqu'un d'autre le lit, que liront-ils alors? Je ne sais pas pourquoi vous avez choisi de sélectionner spécifiquement un verrou en lecture-écriture "rentrant", mais la ré-entrée signifie que le propriétaire d'un verrou rentrant peut le verrouiller à nouveau () et tous les lock()appels ultérieurs après le premier reviendra immédiatement et avec succès. c'est à dire que vous pouvez verrouiller avec succès quelque chose que vous possédez déjà.
ArjunShankar

2
Vous mentionnez également que "je pensais que le verrouillage en écriture pouvait être obtenu à tout moment, sinon la famine pour l'écriture pourrait se produire en raison de la lecture continue" - cela ne peut tout simplement pas être. Un verrou d'écriture ne peut pas être obtenu alors qu'une autre entité détient déjà un verrou de lecture / écriture. Ce qui peut arriver, c'est que si plusieurs entités attendent déjà de verrouiller un objet, alors une attente a la writerpréférence sur les lecteurs en attente lorsque le verrou choisit qui obtient le verrou suivant (lorsqu'il est déverrouillé par son propriétaire actuel). C'est une question de politique .
ArjunShankar

Je vous remercie! J'ai choisi ReentrantReadWriteLock; car c'est la classe d'implémentation de ReadWriteLock en java. Ensuite, y a-t-il un indicateur levé ou une priorité plus élevée pour indiquer que de nouveaux threads de lecture doivent attendre lorsque le thread d'écriture commence à attendre? Parce que comment éviter la famine du thread d'écriture en raison d'une demande de lecture continue?
Kanagavelu Sugumar

34

C'est assez simple. Les verrous de lecture sont également appelés verrous partagés, car plusieurs processus peuvent lire en même temps. Le but d'un verrou de lecture est d'empêcher l'acquisition d'un verrou d'écriture par un autre processus. En revanche, un verrou d'écriture inhibe toutes les autres opérations pendant qu'une opération d'écriture se termine, c'est pourquoi il est décrit comme exclusif.

Ainsi, un verrou de lecture dit "vous pouvez lire maintenant mais si vous voulez écrire, vous devrez attendre" alors qu'un verrou d'écriture dit "vous devrez attendre".


Je sais que vous faites des recherches pour soutenir vos études, mais je ne peux pas résister à l'envie de faire des conférences.

L'utilisation incompétente du verrouillage est l'une des principales causes de maux de tête liés aux performances. L'utilisation d'un système de verrouillage qui différencie les verrous en lecture et en écriture est un bon début, mais une conception soignée peut parfois éliminer une grande partie du besoin de verrouiller. Par exemple, l'état de session ne doit jamais être conservé dans une collection globale par élément d'état.

J'ai effectivement vu cela se faire. C'est un design atroce, provoquant un boxing et un changement dans une collection pour chaque dernier changement d'état de session, entraînant un verrou d'écriture prolongé. Les frais généraux étaient rédhibitoires, réduisant efficacement le serveur à un comportement à thread unique.

Le simple fait d'agréger tout l'état de session dans une structure était une énorme amélioration. Les modifications apportées à l'état de session ont simplement changé les valeurs des membres de la structure d'état d'une session. Puisqu'aucune autre session n'avait l'occasion ni même la possibilité de référencer directement l'état d'une session, la seule collection mise à jour était la liste des sessions. En conséquence, le verrouillage était totalement inutile pendant une session, uniquement au début et à la fin, et le débit a augmenté d'un facteur de 3000.

L'autre scénario de verrouillage courant concerne les ressources partagées entre les threads d'une application utilisateur. La plupart des frameworks modernes abordent ce problème en utilisant des messages plutôt que des verrous; lorsque vous «passez au thread d'interface utilisateur», vous mettez en file d'attente un message contenant un pointeur de fonction et certains paramètres (ou un délégué et un cadre de pile selon l'implémentation).


6
  • Un verrou exclusif ou en écriture donne à un processus un accès exclusif pour écrire dans la partie spécifiée du fichier. Lorsqu'un verrou en écriture est en place, aucun autre processus ne peut verrouiller cette partie du fichier.

  • Un verrou partagé ou en lecture interdit à tout autre processus de demander un verrou en écriture sur la partie spécifiée du fichier. Cependant, d'autres processus peuvent demander des verrous de lecture.

Pour en savoir plus: http://www.gnu.org/software/libc/manual/html_node/File-Locks.html


2

Le principe est également le même du côté de la base de données. Selon la documentation Oracle

Le mode de verrouillage exclusif empêche le partage de la ressource associée. Ce mode de verrouillage est obtenu pour modifier les données. La première transaction à verrouiller exclusivement une ressource est la seule transaction qui peut modifier la ressource jusqu'à ce que le verrou exclusif soit libéré.

Le mode de verrouillage de partage permet de partager la ressource associée, en fonction des opérations impliquées. Plusieurs utilisateurs lisant des données peuvent partager les données, en maintenant des verrous de partage pour empêcher l'accès simultané par un écrivain (qui a besoin d'un verrou exclusif). Plusieurs transactions peuvent
acquérir des verrous de partage sur la même ressource.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.