Différence : 1. Mutex est utilisé pour l'exclusion mutuelle des threads et le sémaphore est utilisé pour la synchronisation des threads ; 2. La valeur du mutex ne peut être que 0 ou 1 et la valeur du sémaphore peut être un entier non négatif ; 3. Mutex Le verrouillage ; et le déverrouillage de la quantité doit être utilisé en conséquence par le même thread. Le sémaphore peut être libéré par un thread et obtenu par un autre thread.
L'environnement d'exploitation de ce tutoriel : système Windows 7, ordinateur Dell G3.
La différence entre mutex et sémaphore
1. Mutex est utilisé pour l'exclusion mutuelle des threads, et le sémaphore est utilisé pour la synchronisation des threads.
C'est la différence fondamentale entre les mutex et les sémaphores, c'est-à-dire la différence entre l'exclusion mutuelle et la synchronisation.
Exclusion mutuelle : signifie qu'une certaine ressource ne permet qu'à un seul visiteur d'y accéder en même temps, ce qui est unique et exclusif. Mais l’exclusion mutuelle ne peut pas limiter l’ordre dans lequel les visiteurs accèdent aux ressources, c’est-à-dire que l’accès n’est pas ordonné.
Synchronisation : fait référence à l'accès ordonné aux ressources par les visiteurs via d'autres mécanismes sur la base de l'exclusion mutuelle (dans la plupart des cas). Dans la plupart des cas, la synchronisation implémente déjà l'exclusion mutuelle, en particulier lorsque toutes les écritures sur les ressources doivent s'exclure mutuellement. Quelques cas permettent à plusieurs visiteurs d'accéder aux ressources en même temps
2 La valeur du mutex ne peut être que 0/1 et la valeur du sémaphore peut être un entier non négatif.
En d'autres termes, un mutex ne peut être utilisé que pour un accès mutuel exclusif à une ressource, et il ne peut pas implémenter l'exclusion mutuelle multithread de plusieurs ressources. Le sémaphore peut réaliser une exclusion mutuelle multithread et une synchronisation de plusieurs ressources similaires. Lorsque le sémaphore est un sémaphore à valeur unique, un accès mutuellement exclusif à une ressource peut également être réalisé.
3. Le verrouillage et le déverrouillage du mutex doivent être utilisés respectivement par le même thread. Le sémaphore peut être libéré par un thread et obtenu par un autre thread.
Mutex (Mutex)
Mutex est une structure de données qui représente le phénomène d'exclusion mutuelle et est également utilisée comme sémaphore binaire. Un mutex est essentiellement un signal binaire sensible au multitâche qui peut être utilisé pour synchroniser le comportement de plusieurs tâches. Il est souvent utilisé pour protéger les sections critiques de code contre les interruptions et pour partager les ressources utilisées lors de la synchronisation.
Mutex est essentiellement un verrou, offrant un accès exclusif aux ressources, le rôle principal de Mutex est donc l'exclusion mutuelle. La valeur de l'objet Mutex n'a que deux valeurs 0 et 1. Ces deux valeursreprésentent également respectivement les deux états de Mutex. La valeur est 0, ce qui indique l'état de verrouillage. L'objet actuel est verrouillé. Si le processus/thread utilisateur tente de verrouiller les ressources critiques, il entrera dans la file d'attente et attendra. La valeur est 1, ce qui indique l'état inactif. L'objet est inactif et le processus/thread utilisateur peut verrouiller les ressources critiques. Ensuite, la valeur Mutex diminue de 1 et devient 0.
Mutex peut être résumé en quatre opérations :
-Créer
-Verrouiller
-Déverrouiller
-Détruire
Mutex peut avoir une valeur initiale lors de sa création, ce qui signifie qu'une fois le Mutex créé, il est État verrouillé ou état inactif. Dans le même thread, afin d'éviter les blocages, le système ne permet pas de verrouiller le Mutex deux fois de suite (le système revient généralement immédiatement après le deuxième appel). En d’autres termes, les deux opérations correspondantes de verrouillage et de déverrouillage doivent être effectuées dans le même thread.
Fonctions Mutex fournies dans différents systèmes d'exploitation :
Action/Système
Win32
Linyx
Solaris
Créer
CréerMutex
pthread_mutex_init
mutex_init
lock
WaitForSingleObject
pthread_mutex_lock
mutex_lock
unlock
ReleaseMutex
pthread_mutex_unlock
Umutex_unlock
Destruction
Closehandle
pthread_mutex_destroy
mutex_destroy
Le blocage se produit principalement lorsqu'il existe plusieurs verrous dépendants et se produit lorsqu'un thread tente de verrouiller le mutex dans l'ordre opposé à celui d'un autre thread. Comment éviter un blocage est une chose à laquelle il convient d'accorder une attention particulière lors de l'utilisation de mutex.
De manière générale, il existe plusieurs principes de base non écrits :
Vous devez obtenir un verrou avant d'opérer sur des ressources partagées.
Assurez-vous de déverrouiller le verrou après avoir terminé l'opération.
Occupez l’écluse le moins longtemps possible.
S'il y a plusieurs verrous, si l'ordre d'acquisition est ABC, l'ordre de libération doit également être ABC.
Lorsqu'un thread revient avec une erreur, il doit libérer le verrou qu'il a acquis.
Peut-être que certains lecteurs sont curieux, comment implémenter les opérations de « suspendre l'attente » et de « réveiller le fil d'attente » ? Chaque Mutex a une file d'attente. Si un thread veut attendre sur le Mutex, il doit d'abord s'ajouter à la file d'attente, puis définir l'état du thread sur veille, puis appeler la fonction de planification pour passer à un autre thread. Si un thread souhaite réveiller d'autres threads dans la file d'attente, il lui suffit de retirer un élément de la file d'attente, de changer son état de veille à prêt et de rejoindre la file d'attente prête. Il peut ensuite passer au réveil le suivant. heure à laquelle la fonction de planification est exécutée.
Normalement, si le même thread appelle lock deux fois, lors du deuxième appel, parce que le verrou est déjà occupé, le thread raccrochera et attendra que d'autres threads libèrent le verrou. Cependant, le verrou est occupé par lui-même. le thread est à nouveau suspendu sans possibilité de libérer le verrou, il est donc toujours dans un état d'attente suspendu. C'est ce qu'on appelle un blocage. Une autre situation de blocage typique est la suivante : le thread A acquiert le verrou 1 et le thread B acquiert le verrou 2. À ce moment-là, le thread A appelle le verrou pour tenter d'acquérir le verrou 2. Par conséquent, il doit se bloquer et attendre que le thread B se libère. lock 2, et à ce moment-là, le thread B appelle également lock pour essayer d'obtenir le verrou 1. Par conséquent, il doit attendre que le thread A libère le verrou 1, de sorte que les threads A et B sont dans un état suspendu pour toujours. Il n'est pas difficile d'imaginer que si davantage de threads et davantage de verrous sont impliqués, le problème d'un éventuel blocage deviendra compliqué et difficile à juger.
Semaphore
Le sémaphore, parfois appelé sémaphore, est une installation utilisée dans un environnement multithread. Il est chargé de coordonner les différents threads pour s'assurer qu'ils peuvent utiliser les ressources publiques correctement et raisonnablement.
Les sémaphores peuvent être divisés en plusieurs catégories :
Sémaphore binaire (sémaphore binaire) : Seul le sémaphore est autorisé à prendre une valeur de 0 ou 1, et il ne peut être acquis que par un seul thread à la fois.
Sémaphore entier : La valeur du sémaphore est un nombre entier, qui peut être obtenu par plusieurs threads en même temps jusqu'à ce que la valeur du sémaphore devienne 0.
Enregistrer le sémaphore : En plus d'une valeur entière (count), chaque sémaphore s possède également une liste de file d'attente, qui est l'identité de chaque thread bloqué dans le sémaphore. Lorsqu'un sémaphore est libéré et que la valeur est incrémentée de un, le système réveille automatiquement un thread en attente de la file d'attente, lui permettant d'obtenir le sémaphore, et en même temps le sémaphore est décrémenté de un.
Le sémaphore contrôle l'accès aux ressources partagées via un compteur. La valeur du sémaphore est un entier non négatif, et tous les threads qui le transmettent décrémenteront l'entier de un. Si le compteur est supérieur à 0, l'accès est autorisé et le compteur est décrémenté de 1 ; s'il est 0, l'accès est interdit et tous les threads tentant de le transmettre seront en attente.
Le résultat du calcul du compteur est le pass qui permet d'accéder à la ressource partagée. Par conséquent, pour accéder à une ressource partagée, un thread doit obtenir un laissez-passer du sémaphore. Si le nombre du sémaphore est supérieur à 0, alors ce thread obtient un laissez-passer, ce qui entraînera une décrémentation du nombre du sémaphore. bloquera jusqu'à ce qu'il obtienne une passe. Lorsque ce thread n'a plus besoin d'accéder à la ressource partagée, il libère la passe, ce qui entraîne l'incrémentation du compteur du sémaphore, et si un autre thread attend la passe, ce thread obtiendra la passe à ce moment-là.
Le sémaphore peut être résumé en cinq opérations :
- Créer Créer
- Attendre Attendre :
Le thread attend le sémaphore Si la valeur est supérieure à 0, elle est obtenue, et la valeur. est réduit de un s'il n'est égal qu'à 0, Ensuite, le thread entrera en état de veille jusqu'à ce que la valeur du sémaphore soit supérieure à 0 ou expire.
-Release Post
exécute la libération du sémaphore, et la valeur est augmentée de un ; s'il y a un thread en attente à ce moment, le thread est réveillé.
-Essayer d'attendre TryWait
Si TryWait est appelé, le thread n'obtient pas réellement le sémaphore, mais vérifie si le sémaphore peut être obtenu si la valeur du sémaphore est supérieure à 0, TryWait renvoie le succès sinon, il renvoie l'échec.
-Détruire
Semaphore peut être utilisé pour protéger deux segments de code clé ou plus. Ces segments de code clé ne peuvent pas être appelés simultanément. Avant d'entrer dans une section critique de code, le thread doit obtenir un sémaphore. S’il n’y a aucun thread dans la section critique du code, le thread entre immédiatement dans cette partie du diagramme. Une fois la section critique du code terminée, le thread doit libérer le sémaphore. Les autres threads qui souhaitent accéder à cette section de code critique doivent attendre que le premier thread libère le sémaphore. Pour terminer ce processus, vous devez créer un sémaphore, puis placer les VIs Acquérir un sémaphore et Libérer un sémaphore au début et à la fin de chaque section de code critique. Assurez-vous que ces VIs de sémaphore font référence au sémaphore créé à l'origine.
Action/Système
Win32
POSIX
Create
CreateSemaphore
sem_init
Attendez
WaitForSingleObject
sem _wait
release
ReleaseMutex
sem _post
j'essaie d'attendre
WaitForSingleObject
sem _trywait
destroy
CloseHandle
sem_destroy
Pour plus de connaissances connexes, veuillez visiter la colonne FAQ !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn