Quelqu’un peut-il expliquer la différence entre:
Je ne peux pas le comprendre. Il me semble que les deux premiers sont les mêmes?
Bonne question Je me trompe peut-être .. Laissez-moi essayer .. Révision # 2 de ma réponse orig .. avec un peu plus de compréhension. Merci de me faire lire 🙂
serrure (obj)
Moniteurs
L’utilisation d’un verrou ou d’un moniteur est utile pour empêcher l’exécution simultanée de blocs de code sensibles au thread, mais ces constructions ne permettent pas à un thread de communiquer un événement à un autre. Cela nécessite des événements de synchronisation , qui sont des objects dont l’un des deux états, signalé et non signalé, peut être utilisé pour activer et suspendre les threads. Mutex, les sémaphores sont des concepts de niveau OS. Par exemple, avec un mutex nommé, vous pouvez synchroniser plusieurs exe (gérés) (en vous assurant qu’une seule instance de votre application s’exécute sur la machine).
Mutex:
Sémaphores (blessé au cerveau).
LA PAGE À LIRE – Synchronisation des threads (C #)
Re “Utilisation d’autres classes de synchronisation .Net” – certaines des autres que vous devez connaître:
Il y a aussi plus de constructions de locking (faible surcharge) dans CCR / TPL (les CTP Parallel Extensions ) – mais IIRC, elles seront disponibles dans .NET 4.0
Comme indiqué dans ECMA, et comme vous pouvez l’observer à partir des méthodes Reflected, l’instruction de locking est fondamentalement équivalente à
object obj = x; System.Threading.Monitor.Enter(obj); try { … } finally { System.Threading.Monitor.Exit(obj); }
L’exemple ci-dessus montre que les moniteurs peuvent verrouiller des objects.
Mutexe sont utiles lorsque vous avez besoin d’une synchronisation interprocess car ils peuvent verrouiller un identificateur de chaîne. Le même identificateur de chaîne peut être utilisé par différents processus pour acquérir le verrou.
Les sémaphores sont comme les mutex sur les stéroïdes, ils permettent un access simultané en fournissant un nombre maximum d’access simultanés ». Une fois la limite atteinte, le sémaphore commence à bloquer tout access supplémentaire à la ressource jusqu’à ce que l’un des appelants libère le sémaphore.
J’ai fait les classes et le support CLR pour le threading dans DotGNU et j’ai quelques reflections …
Sauf si vous avez besoin de verrous inter-processus, vous devriez toujours éviter d’utiliser Mutex & Semaphores. Ces classes dans .NET sont des enveloppes autour de Win32 Mutex et des sémaphores et sont plutôt lourdes (elles nécessitent un changement de contexte dans le kernel, ce qui est coûteux – surtout si votre verrou n’est pas en conflit).
Comme d’autres sont mentionnés, l’instruction de locking C # est la magie du compilateur pour Monitor.Enter et Monitor.Exit (existant dans un try / finally).
Les moniteurs ont un mécanisme de signal / attente simple mais puissant que les mutex n’ont pas via les méthodes Monitor.Pulse / Monitor.Wait. L’équivalent Win32 serait des objects événement via CreateEvent qui existent également dans .NET en tant que WaitHandles. Le modèle Pulse / Wait est similaire à pthread_signal et pthread_wait d’Unix mais est plus rapide car il peut s’agir d’opérations en mode utilisateur dans le cas non contesté.
Monitor.Pulse / Wait est simple à utiliser. Dans un thread, nous verrouillons un object, vérifions un drapeau / state / property et si ce n’est pas ce que nous attendons, appelons Monitor.Wait qui libère le verrou et attend qu’une impulsion soit envoyée. Lorsque l’attente retourne, nous effectuons une boucle et vérifions à nouveau la propriété flag / state /. Dans l’autre thread, nous verrouillons l’object chaque fois que nous modifions la propriété flag / state /, puis appelons PulseAll pour réveiller les threads d’écoute.
Souvent, nous voulons que nos classes soient sûres pour les threads, donc nous mettons des verrous dans notre code. Cependant, il arrive souvent que notre classe ne soit utilisée que par un seul thread. Cela signifie que les verrous ralentissent inutilement notre code … c’est là que des optimisations intelligentes dans le CLR peuvent aider à améliorer les performances.
Je ne suis pas sûr de l’implémentation des verrous par Microsoft, mais dans DotGNU et Mono, un indicateur d’état de locking est stocké dans l’en-tête de chaque object. Chaque object en .NET (et Java) peut devenir un verrou, de sorte que chaque object doit le supporter dans son en-tête. Dans l’implémentation DotGNU, il y a un indicateur qui vous permet d’utiliser une table de hachage globale pour chaque object utilisé comme verrou, ce qui a l’avantage d’éliminer une surcharge de 4 octets pour chaque object. Ce n’est pas génial pour la mémoire (en particulier pour les systèmes embarqués qui ne sont pas très threadés) mais a un impact sur les performances.
Mono et DotGNU utilisent tous deux des mutex pour effectuer des opérations de locking / attente, mais utilisent des opérations de comparaison et d’échange de style spinlock pour éliminer le besoin de réellement effectuer des verrous, sauf si cela est vraiment nécessaire:
Vous pouvez voir un exemple de la façon dont les moniteurs peuvent être implémentés ici:
http://cvs.savannah.gnu.org/viewvc/dotgnu-pnet/pnet/engine/lib_monitor.c?revision=1.7&view=markup
Une mise en garde supplémentaire pour le locking sur un Mutex partagé que vous avez identifié avec un identifiant de chaîne est qu’il sera par défaut un mutex “Local \” et ne sera pas partagé entre les sessions dans un environnement de serveur Terminal Server.
Préfixez votre identifiant de chaîne avec “Global \” pour vous assurer que l’access aux ressources système partagées est correctement contrôlé. Je rencontrais tout un tas de problèmes lors de la synchronisation des communications avec un service exécuté sous le compte SYSTEM avant de m’en rendre compte.
Je voudrais essayer d’éviter “lock ()”, “Mutex” et “Monitor” si vous le pouvez …
Découvrez le nouvel espace de noms System.Collections.Concurrent dans .NET 4
Il possède de belles classes de collecte sécurisées pour les threads
http://msdn.microsoft.com/en-us/library/system.collections.concurrent.aspx
ConcurrentDictionary roches! plus de locking manuel pour moi!