¿Cuál es la diferencia entre lock y Mutex?

Respuestas:

146

Un bloqueo es específico para el dominio de aplicación, mientras que Mutex para el sistema operativo le permite realizar el bloqueo y la sincronización entre procesos (IPC).

Darin Dimitrov
fuente
95

lockes una palabra clave del compilador, no una clase u objeto real. Es un envoltorio sobre la funcionalidad de la Monitorclase y está diseñado para facilitar el Monitortrabajo en el caso común.

La Monitor(y la lockpalabra clave) están, como dijo Darin, restringidas a AppDomain. Principalmente porque se requiere una referencia a una dirección de memoria (en forma de un objeto instanciado) para administrar el "bloqueo" y mantener la identidad delMonitor

El Mutex, por otro lado, es un contenedor .Net alrededor de una construcción del sistema operativo, y se puede utilizar para la sincronización de todo el sistema, utilizando datos de cadena (en lugar de un puntero a los datos) como su identificador. Dos mutexes que hacen referencia a dos cadenas en dos direcciones de memoria completamente diferentes, pero que tienen los mismos datos , en realidad utilizarán el mismo mutex del sistema operativo.

Toby
fuente
54

A Mutexpuede ser local para un proceso o para todo el sistema . MSDN :

Los mutexes son de dos tipos: mutexes locales, que no tienen nombre, y mutexes con nombre del sistema. Un mutex local solo existe dentro de su proceso.

Además, se debe tener especial cuidado, detallado también en la misma página, cuando se utiliza un mutex en todo el sistema en un sistema con Terminal Services.

Una de las diferencias entre Mutexy lockes que Mutexutiliza una construcción a nivel de núcleo , por lo que la sincronización siempre requerirá al menos una transición de espacio espacio-núcleo de usuario.

lock- eso es realmente un acceso directo a la Monitorclase , por otro lado, trata de evitar la asignación de recursos del núcleo y la transición al código del núcleo (y, por lo tanto, es más ágil y rápido, si uno tiene que encontrar una construcción WinAPI a la que se parezca, sería CriticalSection).

La otra diferencia es lo que otros señalan: un nombre Mutex puede usarse en todos los procesos.

A menos que uno tenga necesidades especiales o requiera sincronización entre procesos, es mejor seguir lock(aka Monitor) ˛

Hay varias otras diferencias "menores", como cómo se maneja el abandono, etc.

Se puede decir lo mismo sobre ReaderWriterLocky ReaderWriterLockSlimen 3.5, Semaphorey lo nuevo SemaphoreSlimen .NET 4.0, etc. Es cierto que las últimas xxSlimclases no se pueden usar como primitivas de sincronización en todo el sistema, pero nunca se suponía que debían hacerlo, sino "solo". ser más rápido y más amigable con los recursos.

Andras Vass
fuente
25

Utilizo un Mutex para verificar si ya tengo una copia de la aplicación ejecutándose en la misma máquina.

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
fuente
8

Ya se ha dicho mucho, pero para simplificar, aquí está mi opinión.

bloqueo -> Fácil de usar, envoltorio en el monitor, se bloquea a través de hilos en un dominio de aplicación.

mutex sin nombre -> similar al bloqueo, excepto que el alcance de bloqueo es mayor y está en AppDomain en un proceso.

Mutex con nombre -> el alcance de bloqueo es incluso más que el mutex sin nombre y es un proceso cruzado en un sistema operativo.

Entonces, ahora que hay opciones, debe elegir la que mejor se adapte a su caso.

Prakash Tripathi
fuente
Como he entendido por las respuestas y los ejemplos de mutex aquí msdn.microsoft.com/en-us/library/… : un mutex sin nombre actúa igual que un candado. Sin embargo, mutex.WaitOne (1000) nos da la oportunidad de agotar el tiempo de espera del bloqueo. Por otro lado, Monitor. TryEnter también nos da esa habilidad. Como se mencionó, Mutex es una envoltura. Por lo tanto, usaría un bloqueo o monitor en lugar de un mutex sin nombre. Pero si se requiere un bloqueo entre procesos, un mutex con nombre es el camino a seguir. Por favor, corríjame si estoy equivocado.
Koray
6

Mutex es un proceso cruzado y habrá un ejemplo clásico de no ejecutar más de una instancia de una aplicación.

El segundo ejemplo es decir que está teniendo un archivo y no desea que un proceso diferente acceda al mismo archivo, puede implementar un Mutex pero recuerde una cosa que Mutex es un sistema operativo amplio y no puede usarse entre dos procesos remotos.

El bloqueo es una forma más simple de proteger la sección de su código y es específico del dominio de la aplicación, puede reemplazar el bloqueo con Moniters si desea una sincronización más controlada.

TalentTuner
fuente
1

Pocas diferencias menores que no se mencionaron en las respuestas:

  1. En el caso de usar bloqueos, puede estar seguro de que el bloqueo se liberará cuando ocurra una excepción dentro del bloque del bloqueo.
    Esto se debe a que la cerradura usa monitores debajo del capó y se implementa de esta manera:

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

    Por lo tanto, en cualquier caso, se libera el bloqueo y no es necesario liberarlo manualmente (como lo haría para los mutexes).

  2. Para los bloqueos, generalmente usa un objeto privado para bloquear (y debería usar ).
    Esto se hace por muchas razones. (Más información: ver esta respuesta y documentación oficial ).

Por lo tanto, en caso de bloqueos, no puede (accidentalmente obtener) acceso al objeto bloqueado desde el exterior y causar algún daño.
Pero en el caso de Mutex, puede, ya que es común tener un Mutex que está marcado como público y se usa desde cualquier lugar.

Solo sombra
fuente