De verrouillage, mutex, sémaphore... quelle est la différence?
J'ai entendu ces mots relatifs à la programmation simultanée, mais quelle est la différence entre eux?
- sna;stackoverflow.com/a/346678/1697099
- La meilleure explication que j'ai jamais vu: crystal.uta.edu/~ylei/cse6324/data/sémaphore.pdf
- Double Possible de la Différence entre le binaire sémaphore mutex et de
Vous devez vous connecter pour publier un commentaire.
Un lock permet à un seul thread à entrer dans la partie qui est verrouillé et que le verrou n'est pas partagé avec les autres processus.
Un mutex est la même qu'une serrure, mais il peut être à l'échelle du système (partagé par plusieurs processus).
Un sémaphore fait la même chose à un mutex, mais permet x nombre de threads d'entrer, ce qui peut être utilisé par exemple pour limiter le nombre de cpu, io ou de la ram intensive tâches en cours d'exécution en même temps.
Pour un poste plus détaillées sur les différences entre les mutex et sémaphore lire ici.
Vous avez également lire/écrire des verrous qui permet un nombre illimité de lecteurs ou de 1 écrivain à un moment donné.
mutex
ils sont toujours référencement de l'OS manipulés un? Aussi une explication simple de la façon dont les moniteurs et les sémaphores travail serait également assez bon pour cette question.You can use a mutex object to protect a shared resource from simultaneous access by multiple threads or processes.
Il y a beaucoup d'idées fausses au sujet de ces mots.
C'est à partir d'un post précédent (https://stackoverflow.com/a/24582076/3163691) qui s'adapte superbe ici:
1) Section Critique= objet Utilisateur utilisé pour permettre l'exécution de juste un thread actif de beaucoup d'autres dans un délai d'un processus de. Les autres threads sélectionnés (@ l'acquisition de cet objet) sont mis à sommeil.
[Sans interprocessus capacité, très primitive de l'objet].
2) Mutex, Sémaphore (aka Mutex)= objet de Noyau utilisé pour permettre l'exécution de juste un thread actif de beaucoup d'autres, entre les différents processus. Les autres threads sélectionnés (@ l'acquisition de cet objet) sont mis à sommeil. Cet objet prend en charge thread à la propriété, le fil notification de résiliation, la récursivité (plusieurs 'acquérir' des appels de même thread) et "inversion de priorité évitement".
[Interprocessus capacité, très sûr à utiliser, une sorte de "haut niveau" de la synchronisation de l'objet].
3) Comptage Sémaphore (aka Sémaphore)= objet de Noyau utilisé pour permettre l'exécution de un groupe de threads actifs de beaucoup d'autres. Les autres threads sélectionnés (@ l'acquisition de cet objet) sont mis à sommeil.
[Interprocessus capacité cependant pas très sûr à utiliser car il manque suivantes mutex attributs: fil notification de résiliation, la récursivité?, 'inversion de priorité évitement"?, etc].
4) Et maintenant, à parler de "spinlocks", d'abord quelques définitions:
Région critique= Une région de mémoire partagée par 2 ou plusieurs processus.
Lock= Une variable dont la valeur permet ou interdit l'entrée à une "critique de la région". (Il pourrait être mis en œuvre comme un simple indicateur booléen').
Occupé attente= Continuellement test d'une variable jusqu'à une certaine valeur apparaît.
Enfin:
Spin-lock (aka Spinlock)= Un de verrouillage qui utilise occupé attente. (L'acquisition de la de verrouillage est faite par xchg ou similaire opérations atomiques).
[Sans fil de couchage, utilisé surtout au niveau du noyau seulement. Ineffcient pour le niveau de l'Utilisateur code].
Un dernier commentaire, je ne suis pas sûr, mais je suis prêt à parier beaucoup d'argent que les 3 premiers synchronisation d'objets (#1, #2 et #3) faire usage de cette simple bête (#4) dans le cadre de leur mise en œuvre.
Une bonne journée!.
Références:
-En Temps réel des Concepts pour les Systèmes Embarqués par les Qing Li avec Caroline Yao (CMP Livres).
-Systèmes d'Exploitation modernes (3e) par Andrew Tanenbaum (Pearson Internationale de l'Éducation).
-Programmation d'Applications pour Microsoft Windows (4e) par Jeffrey Richter (Microsoft Programmation de la Série).
Aussi, vous pouvez prendre un coup d'oeil à regarder:
https://stackoverflow.com/a/24586803/3163691
Prendre un coup d'oeil à Le Multithreading Tutoriel par Jean-Kopplin.
Dans la section de Synchronisation Entre les Threads, il explique la différence entre événement, de le verrouiller un mutex, sémaphore, waitable minuterie
La plupart des problèmes peuvent être résolus en utilisant (i) bloque juste, (ii) juste sémaphores, ..., ou (iii) une combinaison des deux! Comme vous l'avez découvert, ils sont très similaires: les deux éviter des conditions de course, les deux ont
acquire()
/release()
opérations, à la fois la cause de zéro ou plus de fils d'être bloqué ou que l'on soupçonne...Vraiment, la différence se situe uniquement sur comment ils verrouillage et déverrouillage de l'.
Pour les deux écluses/sémaphores, en essayant d'appeler
acquire()
tandis que le primitif est à l'état 0 provoque l'invocation thread est suspendu. Pour les serrures, les tentatives visant à acquérir le verrou est dans l'état 1 sont couronnées de succès. Pour les sémaphores, les tentatives visant à acquérir le verrou dans les états {1, 2, 3, ...} sont couronnées de succès.Pour les écluses de l'état l'état 0, si même thread qui avait déjà appelé
acquire()
, maintenant des appels à la libération, puis la sortie est réussi. Si un différents fil essayé -- c'est jusqu'à la mise en œuvre/bibliothèque de ce qui se passe (généralement la tentative ignoré ou une erreur est renvoyée). Pour les sémaphores à l'état 0, tout thread peut appeler la libération et elle sera couronnée de succès (quel que soit le thread précédent utilisé acquérir de mettre le feu à l'état 0).De la discussion qui précède, nous pouvons voir que les serrures ont une notion de propriétaire (le seul fil que l'on peut appeler la libération est le propriétaire), alors que les sémaphores n'ont pas de propriétaire (n'importe quel thread peut appeler release sur un sémaphore).
Ce qui provoque beaucoup de confusion, c'est que, dans la pratique, ils sont de nombreuses variations de ce haut niveau de définition.
Des variations importantes à considérer:
acquire()
/release()
être appelé? -- [Varie massivement]Ces dépend de votre ouvrage /maître de conférences /langue /bibliothèque /environnement.
Voici un rapide tour en constatant à quel point certaines langues répondre à ces détails.
C, C++ (pthreads)
pthread_mutex_t
. Par défaut, ils ne peuvent pas être partagés avec les autres processus (PTHREAD_PROCESS_PRIVATE
), cependant mutex ont un attribut appelé pshared. Lorsqu'il est défini, de sorte que le mutex est partagée entre plusieurs processus (PTHREAD_PROCESS_SHARED
).sem_t
. Semblable à mutex, sémaphores peuvent être partagées entre les threasds de nombreux processus ou maintenu privé pour les threads d'un même processus. Cela dépend de la pshared argument fourni àsem_init
.python (threading.py)
threading.RLock
) est essentiellement le même que le C/C++pthread_mutex_t
s. Les deux sont à la fois réentrant. Cela signifie qu'ils ne peuvent être déverrouillés par le même thread qui l'a enfermé. C'est le cas quesem_t
sémaphores,threading.Semaphore
les sémaphores et lestheading.Lock
les verrous sont non réentrant -- car c'est le cas tout thread peut exécuter déverrouiller la serrure /bas du sémaphore.threading.Semaphore
) est essentiellement le même quesem_t
. Bien qu'avecsem_t
, une file d'attente d'id de thread est utilisé pour retenir l'ordre dans lequel les threads s'est retrouvé bloqué lors de la tentative de verrouillage lorsqu'il est verrouillé. Lorsqu'un thread déverrouille d'un sémaphore, le première fil dans la file d'attente (si il y en a un) est choisie pour être le nouveau propriétaire. Le fil de l'identifiant est retiré de la file d'attente et le sémaphore devient à nouveau verrouillé. Cependant, avecthreading.Semaphore
, un ensemble est utilisé à la place d'une file d'attente, donc l'ordre dans lequel les threads s'est retrouvé bloqué n'est pas stocké -- tout fil dans l'ensemble peut être choisi pour être le prochain propriétaire.Java (java.util.simultanées)
java.util.concurrent.ReentrantLock
) est essentiellement le même que le C/C++pthread_mutex_t
's, et Pythonthreading.RLock
en ce qu'il met en œuvre également un réentrant de verrouillage. Le partage des écluses entre les processus est plus difficile en Java en raison de la JVM agir en tant qu'intermédiaire. Si un thread tente de déverrouiller une serrure, il n'est pas propre, unIllegalMonitorStateException
est levée.java.util.concurrent.Semaphore
) est essentiellement le même quesem_t
etthreading.Semaphore
. Le constructeur de Java sémaphores accepter un équité paramètre booléen qui contrôle si l'utilisation d'un ensemble (false) ou une file d'attente (true) pour stocker les threads en attente.En théorie, les sémaphores sont souvent évoqués, mais dans la pratique, les sémaphores ne sont pas utilisés. Un sémaphore ne détiennent l'état de un entier, de sorte que souvent, c'est plutôt rigide et nombreux sont nécessaires à la fois -- causer des difficultés dans la compréhension du code. Aussi, le fait que tout thread peut lancer un sémaphore est parfois indésirable. Plus orienté objet /de plus haut niveau des primitives de synchronisation /abstractions telles que "les variables de condition" et de "moniteurs" sont utilisés à la place.
Je vais essayer de le couvrir avec des exemples:
De verrouillage: Un exemple où vous utiliseriez
lock
sera partagé dictionnaire dans lequel les éléments (qui doit avoir les clés uniques) sont ajoutés.Le verrou doit s'assurer qu'un thread ne pas entrer dans le mécanisme de code qui est la vérification de l'élément en cours dans le dictionnaire tandis qu'un autre thread (qui est dans la section critique) a déjà passé cette case et est l'ajout de l'article. Si un autre thread tente d'accéder à un blocage de code, il faudra attendre (est bloqué jusqu'à ce que l'objet est libéré.
Sémaphore:
Disons que vous avez un pool de connexions, alors un seul thread peut réserver un élément dans la piscine en attendant le sémaphore pour obtenir une connexion. Il utilise ensuite la connexion et lorsque le travail est terminé libère la connexion par la libération du sémaphore.
Exemple de Code que j'adore c'est un de videur donné par @Patric - ici, il va:
Mutex Il est assez bien
Semaphore(1,1)
et souvent utilisé dans le monde entier (application large sinon sans doutelock
est plus approprié). On pourrait utiliser leMutex
lors de la suppression d'un nœud d'un accessibles dans le monde entier de la liste (la dernière chose que vous voulez un autre thread pour faire quelque chose pendant que vous êtes en train de supprimer le nœud). Lorsque vous acquérirMutex
si différents thread tente d'acquérir le mêmeMutex
il sera mis en sommeil jusqu'à MÊME thread que celui qui a acquis leMutex
libère.Bon exemple sur la création mondiale de mutex est par @deepee
puis à utiliser comme:
Espère que cela vous fait gagner du temps.
Wikipedia a une grande section sur la les différences entre les Sémaphores et les Mutex:
Ma compréhension est qu'un mutex est uniquement pour une utilisation au sein d'un seul processus, mais à travers ses nombreux fils, alors qu'un sémaphore peut être utilisé dans de multiples processus, et à travers leurs séries de fils.
Aussi, un mutex est binaire (c'est soit verrouillé ou non), alors qu'un sémaphore a une notion de comptage, ou une file d'attente de plus d'un verrouillage et déverrouillage des demandes.
Quelqu'un pourrait-il vérifier mon explication? Je parle dans le contexte de Linux, plus précisément de Red Hat Enterprise Linux (RHEL) de la version 6, qui utilise un noyau 2.6.32.
À l'aide de la programmation en C sous Linux variante comme une base de cas pour les exemples.
De verrouillage:
• En général, un très simple de construire binaire dans l'opération soit verrouillé ou déverrouillé
• Pas de notion de thread à la propriété, la priorité, de séquençage etc.
• En général, un verrou de rotation où le fil en permanence pour les serrures de disponibilité.
• En général, s'appuie sur des opérations atomiques par exemple, Test-and-set, compare-and-swap, d'extraction et d'ajouter etc.
• En général, nécessite un support matériel pour opération atomique.
Verrous De Fichier:
• Généralement utilisé pour coordonner l'accès à un fichier par plusieurs processus.
• Plusieurs processus peuvent tenir le verrou en lecture cependant lorsqu'un processus détient le verrou d'écriture aucun autre processus n'est autorisé à acquérir, de lecture ou d'écriture de verrouillage.
• Exemple : troupeau, fcntl etc..
Mutex:
• Mutex appels de fonction pour habitude de travailler dans l'espace du noyau et du système d'appels.
• Il utilise la notion de propriété. Seul le thread qui détient actuellement le mutex pouvez le déverrouiller.
• Mutex n'est pas récursive (Exception: PTHREAD_MUTEX_RECURSIVE).
• Généralement utilisé en Association avec les Variables de Condition et passés comme arguments, par exemple pthread_cond_signal, pthread_cond_wait etc.
• Certains systèmes UNIX permettent de mutex pour être utilisé par plusieurs processus, même si cela peut ne pas être appliquée sur tous les systèmes.
Sémaphore:
• C'est un noyau maintenu entier dont la valeur n'est pas autorisé à tomber en dessous de zéro.
• Il peut être utilisé pour synchroniser les processus.
• La valeur du sémaphore peut être réglé à une valeur supérieure à 1, auquel cas la valeur indique le nombre de ressources disponibles.
• Un sémaphore dont la valeur est limitée à 1 et 0 est appelé un sémaphore binaire.