Quelle est la différence entre Lock et Mutex?

129

Quelle est la différence entre Lock et Mutex? Pourquoi ne peuvent-ils pas être utilisés de manière interchangeable?

RAM
la source

Réponses:

146

Un verrou est spécifique à l'AppDomain, tandis que Mutex au système d'exploitation vous permet d'effectuer le verrouillage et la synchronisation inter-processus (IPC).

Darin Dimitrov
la source
95

lockest un mot-clé du compilateur, pas une classe ou un objet réel. C'est un wrapper autour de la fonctionnalité de la Monitorclasse et est conçu pour faciliter le Monitortravail avec le cas commun.

Le Monitor(et le lockmot - clé) sont, comme l'a dit Darin, limités au AppDomain. Principalement parce qu'une référence à une adresse mémoire (sous la forme d'un objet instancié) est nécessaire pour gérer le "verrou" et conserver l'identité duMonitor

Le Mutex, d'autre part, est un wrapper .Net autour d'une construction de système d'exploitation, et peut être utilisé pour la synchronisation à l'échelle du système, en utilisant des données de chaîne (au lieu d'un pointeur vers des données) comme identifiant. Deux mutex qui référencent deux chaînes dans deux adresses mémoire complètement différentes, mais ayant les mêmes données , utiliseront en fait le même mutex du système d'exploitation.

Toby
la source
54

A Mutexpeut être soit local à un processus, soit à l'échelle du système . MSDN :

Les mutex sont de deux types: les mutex locaux, qui ne sont pas nommés, et les mutex système nommés. Un mutex local n'existe que dans votre processus.

De plus, il faut faire particulièrement attention - détaillé sur la même page également - lors de l'utilisation d'un mutex à l'échelle du système sur un système avec des services Terminal Server.

L'une des différences entre Mutexet lockest qu'il Mutexutilise une construction au niveau du noyau , de sorte que la synchronisation nécessitera toujours au moins une transition espace utilisateur-espace noyau.

lock- c'est vraiment un raccourci vers la Monitorclasse , d'autre part essaie d'éviter d'allouer des ressources du noyau et de passer au code du noyau (et est donc plus léger et plus rapide - si l'on doit trouver une construction WinAPI qui lui ressemble, ce serait CriticalSection).

L'autre différence est ce que les autres soulignent: un named Mutex peut être utilisé dans tous les processus.

Sauf si l'on a des besoins particuliers ou nécessite une synchronisation entre les processus, il vaut mieux s'en tenir à lock(aka Monitor) ˛

Il existe plusieurs autres différences «mineures», comme la façon dont l'abandon est géré, etc.

On peut dire la même chose de ReaderWriterLocket ReaderWriterLockSlimdans 3.5, Semaphoreet du nouveau SemaphoreSlimdans .NET 4.0 etc. Il est vrai que ces dernières xxSlimclasses ne peuvent pas être utilisées comme primitives de synchronisation à l’échelle du système, mais elles n’étaient jamais destinées à - elles étaient "seulement" signifiées pour être plus rapide et plus respectueux des ressources.

Andras Vass
la source
25

J'utilise un Mutex pour vérifier si j'ai déjà une copie de l'application en cours d'exécution sur la même machine.

bool firstInstance;
Mutex mutex = new Mutex(false, @"Local\DASHBOARD_MAIN_APPLICATION", out firstInstance);

if (!firstInstance)
{
    //another copy of this application running 
}
else
{
    //run main application loop here.
}
// Refer to the mutex down here so garbage collection doesn't chuck it out.
GC.KeepAlive(mutex);
Jonathan
la source
8

Beaucoup de choses ont déjà été dites, mais pour faire simple, voici mon avis.

lock -> Simple à utiliser, wrapper sur le moniteur, se verrouille entre les threads dans un AppDomain.

mutex sans nom -> similaire au verrou, sauf que la portée de verrouillage est plus et qu'elle se trouve à travers AppDomain dans un processus.

Mutex nommé -> la portée de verrouillage est encore plus qu'un mutex sans nom et se déroule dans un processus dans un système d'exploitation.

Alors maintenant, les options sont là, vous devez choisir celle qui convient le mieux à votre cas.

Prakash Tripathi
la source
Comme je l'ai compris à partir des réponses et des exemples de mutex ici msdn.microsoft.com/en-us/library/… : un mutex sans nom agit de la même manière qu'un verrou. Cependant, mutex.WaitOne (1000) nous donne une chance d'expirer le verrouillage. D'autre part, Monitor.TryEnter nous donne également cette capacité. Comme mentionné, Mutex est un wrapper. J'utiliserais donc un verrou ou un moniteur au lieu d'un mutex sans nom. Mais si un verrou entre les processus est requis, un mutex nommé est la voie à suivre. S'il vous plait corrigez moi si je me trompe.
Koray
6

Mutex est un processus croisé et il y aura un exemple classique de ne pas exécuter plus d'une instance d'une application.

Le deuxième exemple est que vous avez un fichier et que vous ne voulez pas qu'un processus différent accède au même fichier, vous pouvez implémenter un Mutex mais rappelez-vous une chose que Mutex est un système d'exploitation à l'échelle du système d'exploitation et ne peut pas être utilisé entre deux processus distants.

Lock est le moyen le plus simple de protéger la section de votre code et il est spécifique au domaine d'application, vous pouvez remplacer le verrouillage par des moniteurs si vous souhaitez une synchronisation plus contrôlée.

TalentTuner
la source
1

Quelques différences plus mineures qui n'ont pas été mentionnées dans les réponses:

  1. Dans le cas de l'utilisation de verrous, vous pouvez être sûr que le verrou sera libéré lorsqu'une exception se produit à l'intérieur du bloc du verrou.
    C'est parce que la serrure utilise des moniteurs sous le capot et est implémentée de cette façon:

     object __lockObj = x;
     bool __lockWasTaken = false;
     try
     {
         System.Threading.Monitor.Enter(__lockObj, ref __lockWasTaken);
         // Your code...
     }
     finally
     {
         if (__lockWasTaken) System.Threading.Monitor.Exit(__lockObj);
     }

    Ainsi, dans tous les cas, le verrou est libéré et vous n'avez pas besoin de le libérer manuellement (comme vous le feriez pour les mutex).

  2. Pour Locks, vous utilisez généralement un objet privé pour verrouiller (et vous devez utiliser ).
    Ceci est fait pour de nombreuses raisons. (Plus d'infos: voir cette réponse et la documentation officielle ).

Ainsi, en cas de verrouillage, vous ne pouvez pas (accéder accidentellement) à l'objet verrouillé de l'extérieur et causer des dommages.
Mais dans le cas de Mutex, vous pouvez, car il est courant d'avoir un Mutex qui est marqué comme public et utilisé de n'importe où.

Juste l'ombre
la source