Respuestas:
lock
es una palabra clave del compilador, no una clase u objeto real. Es un envoltorio sobre la funcionalidad de la Monitor
clase y está diseñado para facilitar el Monitor
trabajo en el caso común.
La Monitor
(y la lock
palabra 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.
A Mutex
puede 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 Mutex
y lock
es que Mutex
utiliza 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 Monitor
clase , 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 ReaderWriterLock
y ReaderWriterLockSlim
en 3.5, Semaphore
y lo nuevo SemaphoreSlim
en .NET 4.0, etc. Es cierto que las últimas xxSlim
clases 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.
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);
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.
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.
Pocas diferencias menores que no se mencionaron en las respuestas:
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).
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.