Un mutex es un concepto de programación que se usa con frecuencia para resolver problemas de subprocesos múltiples. Mi pregunta a la comunidad:
¿Qué es un mutex y cómo se usa?
Un mutex es un concepto de programación que se usa con frecuencia para resolver problemas de subprocesos múltiples. Mi pregunta a la comunidad:
¿Qué es un mutex y cómo se usa?
Respuestas:
Cuando estoy teniendo una gran discusión en el trabajo, uso un pollo de goma que guardo en mi escritorio para esas ocasiones. La persona que sostiene el pollo es la única persona a la que se le permite hablar. Si no sostienes el pollo no puedes hablar. Solo puedes indicar que quieres el pollo y esperar hasta que lo consigas antes de hablar. Una vez que haya terminado de hablar, puede devolver el pollo al moderador, que lo entregará a la siguiente persona para que hable. Esto garantiza que las personas no hablen entre sí y que también tengan su propio espacio para hablar.
Reemplaza Chicken con Mutex y person con thread y básicamente tienes el concepto de mutex.
Por supuesto, no existe un mutex de goma. Solo pollo de goma. Mis gatos una vez tuvieron un ratón de goma, pero se lo comieron.
Por supuesto, antes de usar el pollo de goma, debe preguntarse si realmente necesita 5 personas en una habitación y no sería más fácil con una sola persona en la habitación haciendo todo el trabajo. En realidad, esto solo está ampliando la analogía, pero se entiende la idea.
Un Mutex es una bandera mutuamente excluyente. Actúa como un guardián de puerta a una sección de código que permite un hilo y bloquea el acceso a todos los demás. Esto garantiza que el código que se controla solo sea alcanzado por un solo hilo a la vez. Solo asegúrese de liberar el mutex cuando haya terminado. :)
Exclusión mutua. Aquí está la entrada de Wikipedia:
http://en.wikipedia.org/wiki/Mutual_exclusion
El objetivo de un mutex es sincronizar dos hilos. Cuando tiene dos hilos que intentan acceder a un solo recurso, el patrón general es tener el primer bloque de código que intenta acceder para establecer el mutex antes de ingresar el código. Cuando el segundo bloque de código intenta acceder, ve que el mutex está configurado y espera hasta que se complete el primer bloque de código (y desarma el mutex), luego continúa.
Los detalles específicos de cómo se logra esto obviamente varían mucho según el lenguaje de programación.
Cuando tiene una aplicación multiproceso, los diferentes subprocesos a veces comparten un recurso común, como una variable o similar. A menudo no se puede acceder a esta fuente compartida al mismo tiempo, por lo que se necesita una construcción para garantizar que solo un subproceso esté usando ese recurso a la vez.
El concepto se llama "exclusión mutua" (Mutex corto) y es una forma de garantizar que solo se permita un subproceso dentro de esa área, utilizando ese recurso, etc.
La forma de usarlos es específica del idioma, pero a menudo (si no siempre) se basa en un mutex del sistema operativo.
Algunos lenguajes no necesitan esta construcción, debido al paradigma, por ejemplo, la programación funcional (Haskell, ML son buenos ejemplos).
En C #, el mutex común utilizado es el Monitor . El tipo es ' System.Threading.Monitor '. También se puede usar implícitamente a través de la declaración ' lock (Object) '. Un ejemplo de su uso es cuando se construye una clase Singleton.
private static readonly Object instanceLock = new Object();
private static MySingleton instance;
public static MySingleton Instance
{
lock(instanceLock)
{
if(instance == null)
{
instance = new MySingleton();
}
return instance;
}
}
La declaración de bloqueo que usa el objeto de bloqueo privado crea una sección crítica. Requerir que cada hilo espere hasta que finalice el anterior. El primer hilo entrará en la sección e inicializará la instancia. El segundo subproceso esperará, entrará en la sección y obtendrá la instancia inicializada.
Cualquier tipo de sincronización de un miembro estático puede usar la declaración de bloqueo de manera similar.
¿Qué es un mutex ?
El mutex (de hecho, el término mutex es la abreviatura de exclusión mutua), también conocido como spinlock, es la herramienta de sincronización más simple que se utiliza para proteger las regiones críticas y evitar así las condiciones de carrera. Es decir, un subproceso debe adquirir un bloqueo antes de entrar en una sección crítica (en la sección crítica, varios subprocesos comparten una variable común, actualizar una tabla, escribir un archivo, etc.), libera el bloqueo cuando sale de la sección crítica.
¿Qué es una condición de carrera ?
Una condición de carrera ocurre cuando dos o más subprocesos pueden acceder a datos compartidos e intentan cambiarlos al mismo tiempo. Debido a que el algoritmo de programación de subprocesos puede intercambiar entre subprocesos en cualquier momento, no conoce el orden en que los subprocesos intentarán acceder a los datos compartidos. Por lo tanto, el resultado del cambio en los datos depende del algoritmo de programación de subprocesos, es decir, ambos subprocesos "compiten" para acceder / cambiar los datos.
Ejemplo de la vida real:
Cuando estoy teniendo una gran discusión en el trabajo, uso un pollo de goma que guardo en mi escritorio para esas ocasiones. La persona que sostiene el pollo es la única persona a la que se le permite hablar. Si no sostienes el pollo no puedes hablar. Solo puedes indicar que quieres el pollo y esperar hasta que lo consigas antes de hablar. Una vez que haya terminado de hablar, puede devolver el pollo al moderador, que lo entregará a la siguiente persona para que hable. Esto garantiza que las personas no hablen entre sí y que también tengan su propio espacio para hablar.
Reemplaza Chicken con Mutex y person con thread y básicamente tienes el concepto de mutex.
@Xetius
Uso en C #:
Este ejemplo muestra cómo se usa un objeto Mutex local para sincronizar el acceso a un recurso protegido. Debido a que cada subproceso de llamada se bloquea hasta que adquiere la propiedad del mutex, debe llamar al método ReleaseMutex para liberar la propiedad del subproceso.
using System;
using System.Threading;
class Example
{
// Create a new Mutex. The creating thread does not own the mutex.
private static Mutex mut = new Mutex();
private const int numIterations = 1;
private const int numThreads = 3;
static void Main()
{
// Create the threads that will use the protected resource.
for(int i = 0; i < numThreads; i++)
{
Thread newThread = new Thread(new ThreadStart(ThreadProc));
newThread.Name = String.Format("Thread{0}", i + 1);
newThread.Start();
}
// The main thread exits, but the application continues to
// run until all foreground threads have exited.
}
private static void ThreadProc()
{
for(int i = 0; i < numIterations; i++)
{
UseResource();
}
}
// This method represents a resource that must be synchronized
// so that only one thread at a time can enter.
private static void UseResource()
{
// Wait until it is safe to enter.
Console.WriteLine("{0} is requesting the mutex",
Thread.CurrentThread.Name);
mut.WaitOne();
Console.WriteLine("{0} has entered the protected area",
Thread.CurrentThread.Name);
// Place code to access non-reentrant resources here.
// Simulate some work.
Thread.Sleep(500);
Console.WriteLine("{0} is leaving the protected area",
Thread.CurrentThread.Name);
// Release the Mutex.
mut.ReleaseMutex();
Console.WriteLine("{0} has released the mutex",
Thread.CurrentThread.Name);
}
}
// The example displays output like the following:
// Thread1 is requesting the mutex
// Thread2 is requesting the mutex
// Thread1 has entered the protected area
// Thread3 is requesting the mutex
// Thread1 is leaving the protected area
// Thread1 has released the mutex
// Thread3 has entered the protected area
// Thread3 is leaving the protected area
// Thread3 has released the mutex
// Thread2 has entered the protected area
// Thread2 is leaving the protected area
// Thread2 has released the mutex
Aquí hay algunas respuestas excelentes, aquí hay otra gran analogía para explicar qué es mutex :
Considere inodoro individual con llave . Cuando alguien entra, toman la llave y el baño está ocupado . Si alguien más necesita usar el baño, debe esperar en la cola . Cuando la persona en el baño termina , le pasan la llave a la siguiente persona en la cola. Tiene sentido, ¿verdad?
Convierta el inodoro en la historia en un recurso compartido y la clave en un mutex . Llevar la llave al baño (adquirir una cerradura) le permite usarla. Si no hay llave (la cerradura está bloqueada) debe esperar. Cuando la persona devuelve la llave ( suelta la cerradura ), ahora puedes adquirirla.
Para comprender MUTEX al principio, necesita saber qué es la "condición de carrera" y luego solo usted comprenderá por qué se necesita MUTEX. Supongamos que tiene un programa de subprocesos múltiples y tiene dos subprocesos. Ahora, tiene un trabajo en la cola de trabajos. El primer hilo verificará la cola de trabajos y después de encontrar el trabajo comenzará a ejecutarlo. El segundo subproceso también verificará la cola de trabajos y encontrará que hay un trabajo en la cola. Por lo tanto, también asignará el mismo puntero de trabajo. Entonces, ahora que sucede, ambos hilos están ejecutando el mismo trabajo. Esto causará una falla de segmentación. Este es el ejemplo de una condición de carrera.
La solución a este problema es MUTEX. MUTEX es un tipo de bloqueo que bloquea un hilo a la vez. Si otro hilo quiere bloquearlo, el hilo simplemente se bloquea.
El tema de MUTEX en este enlace de archivo pdf realmente vale la pena leer.
Los mutexes son útiles en situaciones en las que necesita forzar el acceso exclusivo a un recurso a través de múltiples procesos, donde un bloqueo regular no ayudará, ya que solo funciona a través de subprocesos.
Mutex: mutex significa Mut UAL Ex conclusión. Significa que a la vez un proceso / hilo puede entrar en la sección crítica. En la programación concurrente en la que múltiples subprocesos / procesos intentan actualizar el recurso compartido (cualquier variable, memoria compartida, etc.) puede generar algún resultado inesperado. (Como el resultado depende del hilo / proceso que obtiene el primer acceso).
Para evitar un resultado tan inesperado, necesitamos un mecanismo de sincronización, que garantice que solo un subproceso / proceso tenga acceso a dicho recurso a la vez.
La biblioteca pthread proporciona soporte para Mutex.
typedef union
{
struct __pthread_mutex_s
{
***int __lock;***
unsigned int __count;
int __owner;
#ifdef __x86_64__
unsigned int __nusers;
#endif
int __kind;
#ifdef __x86_64__
short __spins;
short __elision;
__pthread_list_t __list;
# define __PTHREAD_MUTEX_HAVE_PREV 1
# define __PTHREAD_SPINS 0, 0
#else
unsigned int __nusers;
__extension__ union
{
struct
{
short __espins;
short __elision;
# define __spins __elision_data.__espins
# define __elision __elision_data.__elision
# define __PTHREAD_SPINS { 0, 0 }
} __elision_data;
__pthread_slist_t __list;
};
#endif
Esta es la estructura para el tipo de datos mutex, es decir, pthread_mutex_t. Cuando mutex está bloqueado, __lock está establecido en 1. Cuando está desbloqueado, __lock está establecido en 0.
Esto garantiza que no haya dos procesos / subprocesos que puedan acceder a la sección crítica al mismo tiempo.