2010-10-28 22 views

Respuesta

47

Un mutex es un objeto de exclusión mutua, similar a un semáforo pero que solo permite un casillero a la vez y cuyas restricciones de propiedad pueden ser más estrictas que un semáforo.

Se puede considerar como equivalente a un semáforo de conteo normal (con un recuento de uno) y el requisito de que solo se puede liberar con el mismo hilo que lo bloqueó (a).

Un semáforo, por otro lado, tiene un recuento arbitrario y puede ser bloqueado por ese número de casilleros al mismo tiempo. Y puede no tener el requisito de que sea lanzado por el mismo hilo que lo reclamó (pero, de lo contrario, debe rastrear cuidadosamente quién es el responsable actual, al igual que la memoria asignada).

Entonces, si tiene un número de instancias de un recurso (digamos tres unidades de cinta), podría usar un semáforo con un conteo de 3. Tenga en cuenta que esto no le dice cuál de esas unidades de cinta tiene, solo que tienes un cierto número.

También con semáforos, es posible que un solo casillero bloquee varias instancias de un recurso, como una copia de cinta a cinta. Si tiene un recurso (digamos una ubicación de memoria que no desea dañar), un mutex es más adecuado.

operaciones equivalentes son:

Counting semaphore   Mutual exclusion semaphore 
-------------------------- -------------------------- 
    Claim/decrease (P)     Lock 
    Release/increase (V)    Unlock 

Aparte: en caso de que alguna vez se ha preguntado a las letras extrañas utilizadas para reclamar y la liberación de los semáforos, es porque el inventor era holandés. Probeer te verlagen significa intentar disminuir mientras que verhogen significa aumentar.


(a) ... o puede ser pensado como algo totalmente distinto de un semáforo, lo que puede ser más seguro debido a sus casi-siempre-usos diferentes.

+0

Bien, me encontré semáforo binario también. ¿Cuándo deberíamos ingresar semáforo binario y cuándo deberíamos usar mutex? –

+0

Conceptualmente, un semáforo binario _es_ un mutex, y es equivalente a un semáforo normal con un conteo.Puede haber diferencias en _implementaciones_ del concepto tales como la eficiencia o la propiedad del recurso (puede ser lanzado por alguien que no sea el claimer, lo que no estoy de acuerdo con el BTW; un recurso solo debería ser liberable por el hilo que lo reclamaba).) – paxdiablo

+1

Otra posible diferencia de implementación es el mutex recursivo. Debido a que solo hay un recurso, se puede permitir que un único hilo lo bloquee varias veces (siempre que también lo libere muchas veces). Esto no es tan fácil con un recurso de instancia múltiple, ya que es posible que no sepa si el hilo desea reclamar otra instancia o la misma instancia nuevamente. – paxdiablo

1

Como se señaló, un semáforo con un recuento de uno es lo mismo que un semáforo 'binario' que es lo mismo que un mutex.

Las principales cosas que he visto en los semáforos con un recuento superior al utilizado son las situaciones de productor/consumidor en las que tiene una cola de un cierto tamaño fijo.

Tiene dos semáforos a continuación. El primer semáforo se establece inicialmente como el número de elementos en la cola y el segundo semáforo se establece en 0. El productor realiza una operación P en el primer semáforo y lo agrega a la cola. y hace una operación V en el segundo. El consumidor realiza una operación P en el segundo semáforo, elimina de la cola y luego realiza una operación V en la primera.

De esta forma, el productor se bloquea cada vez que llena la cola y el consumidor se bloquea siempre que la cola esté vacía.

12

Si bien la respuesta de @opaxdiablo es totalmente correcta, me gustaría señalar que el escenario de uso de ambas cosas es bastante diferente. El mutex se usa para proteger partes del código que se ejecutan simultáneamente, los semáforos se usan para un hilo para señalar otro hilo para ejecutar.

/* Task 1 */ 
pthread_mutex_lock(mutex_thing); 
    // Safely use shared resource 
pthread_mutex_unlock(mutex_thing); 



/* Task 2 */ 
pthread_mutex_lock(mutex_thing); 
    // Safely use shared resource 
pthread_mutex_lock(mutex_thing); 

El escenario semáforo es diferente:

/* Task 1 - Producer */ 
sema_post(&sem); // Send the signal 

/* Task 2 - Consumer */ 
sema_wait(&sem); // Wait for signal 

Ver http://www.netrino.com/node/202 para más explicaciones

+2

Tienes razón. Incluso si está utilizando un semáforo con un recuento de uno, está implicando algo sobre lo que está haciendo que si utilizó un mutex. – Omnifarious

+0

No estoy seguro de estar de acuerdo con eso, aunque no estoy _disagree_ con tanta vehemencia que te rechazaré :-) Dices que el patrón de uso de los semáforos es para notificar los hilos, pero eso es exactamente lo que hacen los mutex cuando hay otro hilo esperando en él, y exactamente qué semáforos _no_t_ cuando no hay hilos en 'sema_wait' :-) En mi opinión, son _ tanto_ de recursos y la notificación entregada a otros hilos es un efecto secundario (muy importante, rendimiento- sabio) de la protección. – paxdiablo

+0

'Usted dice que el patrón de uso de los semáforos es notificar a los hilos' Un punto sobre la notificación de hilos. Puede llamar a 'sem_post' desde un manejador de señal de forma segura (http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html), pero no es recomendable llamar' pthread_mutex_lock' y 'pthread_mutex_unlock' desde manejadores de señal (http://manpages.ubuntu.com/manpages/lucid/man3/pthread_mutex_init.3.html#contenttoc4) –

8

ver "el Ejemplo WC" - http://pheatt.emporia.edu/courses/2010/cs557f10/hand07/Mutex%20vs_%20Semaphore.htm:

objeto mutex:

es la llave de un baño. Una persona puede tener la llave, ocupar el baño, en ese momento. Cuando termina, la persona da (libera) la llave a la siguiente persona en la cola.

Oficialmente: "Mutexes se utilizan generalmente para serializar el acceso a una sección de código de reentrantes que no se puede ejecutar simultáneamente por más de un hilo. Un objeto mutex solo permite un hilo en una sección controlada, forzando a otros hilos que intentan para obtener acceso a esa sección para esperar hasta que el primer hilo haya salido de esa sección ". Ref: Symbian Developer Library

(Un mutex es realmente un semáforo con valor 1.)

Semáforo:

es el número de llaves idénticas de aseo gratuitos. Ejemplo, digamos que tenemos cuatro baños con cerraduras y llaves idénticas. El recuento de semáforos (el recuento de claves) se establece en 4 al principio (los cuatro retretes son gratuitos), luego el valor del recuento disminuye a medida que las personas ingresan. Si todos los retretes están llenos, es decir, no quedan claves libres, el recuento de semáforos es 0. Ahora, cuando eq. una persona deja el baño, el semáforo aumenta a 1 (una tecla libre) y se le da a la siguiente persona en la fila.

Oficialmente: "Un semáforo restringe el número de usuarios simultáneos de un recurso compartido hasta un número máximo. Los subprocesos pueden solicitar acceso al recurso (decrementando el semáforo) y pueden indicar que terminaron de usar el recurso (incrementando el semáforo) ". Ref: Symbian Developer Library

35

Es muy importante entender que un mutex no es un semáforo con el recuento de 1!

Esta es la razón por la que hay cosas como los semáforos binarios (que en realidad son semáforos con el recuento 1).

La diferencia entre un objeto mutex y un Binario-semáforo es el principio de la propiedad:

Un mutex es adquirida por una tarea y por lo tanto también deben ser liberados por la misma tarea. Esto hace posible solucionar varios problemas con los semáforos binarios (publicación Accidental, interbloqueo recursivo e inversión de prioridad).

Advertencia: escribí "lo hace posible", si y cómo se solucionan estos problemas depende de la implementación del sistema operativo.

Como el mutex tiene que ser liberado por la misma tarea, no es muy bueno para la sincronización de tareas. Pero si se combina con variables de condición, se obtienen bloques de construcción muy poderosos para construir todo tipo de primitivas ipc.

Así que mi recomendación es: si tienes mutexes y variables de condición implementadas limpiamente (como con POSIX pthreads) úsalos.

usar semáforos sólo si encajan exactamente con el problema que está tratando de resolver, no trate de construir otras primitivas (por ejemplo, rw-cerraduras de los semáforos, utilizar mutex y variables de condición para éstos)

Hay es un montón de malentendidos mutexes y semáforos. La mejor explicación que encontré hasta ahora es en este artículo de 3 partes:

Mutex vs. Semaphores – Part 1: Semaphores

Mutex vs. Semaphores – Part 2: The Mutex

Mutex vs. Semaphores – Part 3 (final part): Mutual Exclusion Problems

+0

Las URL de este sitio contienen caracteres funky y no funcionan, por lo tanto ... Estoy trabajando en ello –

+0

Se corrigieron los caracteres Unicode en los urs, los enlaces ahora funcionan. –

67

Aquí es cómo recuerdo cuándo usar lo que -

Semáforo : Use un semáforo cuando (hilo) desea dormir hasta que otro hilo le indique que se despierte. El semáforo 'abajo' ocurre en un subproceso (productor) y el semáforo 'arriba' (para el mismo semáforo) ocurre en otro subproceso (consumidor) p.ej .: En un problema productor-consumidor, el productor quiere dormir hasta que al menos un nicho esté vacío - solo el hilo del consumidor puede indicar cuándo una ranura de almacenamiento intermedio está vacía.

objeto mutex: Usar un mutex cuando (rosca) desea ejecutar código que no debe ser ejecutado por cualquier otro hilo al mismo tiempo. Mutex 'abajo' sucede en un hilo y mutex 'arriba' debe pasar en el mismo hilo más adelante. por ejemplo .: si está eliminando un nodo de una lista global vinculada, no desea que otro hilo se ensucie con los punteros mientras está eliminando el nodo. Cuando adquiere un mutex y está ocupado eliminando un nodo, si otro hilo intenta adquirir el mismo mutex, se pondrá en modo suspensión hasta que libere el mutex.

Spinlock: Use un spinlock cuando realmente quiera usar un mutex pero su hilo no puede dormir. por ejemplo, un controlador de interrupción dentro del núcleo del sistema operativo nunca debe dormir. Si lo hace, el sistema se congelará/se bloqueará. Si necesita insertar un nodo en la lista de enlaces compartidos globalmente desde el manejador de interrupciones, adquiera un spinlock - insert node - release spinlock.

+0

para agregar a: los semáforos y el mutex son dos formas de proporcionar sincronización. semáforo, puede estar más relacionado con la señalización (por ejemplo, escenario del problema del productor y del consumidor) y mutex, puede estar más relacionado con permitir el acceso a uno por vez (varias solicitudes para acceder al recurso compartido, pero solo una otorgada a la vez). [buen artículo: http://www.geeksforgeeks.org/mutex-vs-semaphore/] – parasrish

7

Tratando de no sonar tonto, pero no puedo evitarlo.

Tu pregunta debería ser ¿cuál es la diferencia entre mutex y semáforos? Y para ser una pregunta más precisa debería ser, '¿cuál es la relación entre mutex y semáforos?'

(. Me hubiera añadido a esa pregunta, pero estoy seguro de que algunos centenares% moderador exceso de celo lo cerraría como duplicado sin entender la diferencia entre la diferencia y la relación)

En la terminología de objetos se puede observar que:

observación.1 Semáforo contiene mutex

observación.2 Mutex no es semáforo y el semáforo no es mutex.

Hay algunos semáforos que actuarán como si fueran mutex, llamados semáforos binarios, pero están volviendo loco NO mutex.

Hay un ingrediente especial llamado Señalización (posix usa la variable de condición para ese nombre), requerido para hacer un semáforo fuera de mutex. Piense en ello como una fuente de notificación. Si dos o más subprocesos están suscritos a la misma fuente de notificación, entonces es posible enviarles un mensaje a UNA o TODO para que se active.

Puede haber uno o más contadores asociados con semáforos, que están protegidos por mutex. El escenario más simple para el semáforo, hay un solo contador que puede ser 0 o 1.

Aquí es donde la confusión se vierte en la lluvia del monzón.

Un semáforo con un contador que puede ser 0 o 1 NO es mutex.

Mutex tiene dos estados (0,1) y una propiedad (tarea). Semáforo tiene un mutex, algunos contadores y una variable de condición.

Ahora, use su imaginación, y cada combinación de uso de contador y cuándo señalizar puede hacer un tipo de semáforo.

  1. contador individual con valor 0 o 1 y la señalización cuando el valor pasa a 1 y luego se desbloquea uno de los tipo esperando en la señal == semáforo binario

  2. contador individual con valor 0 a N y señalización cuando el valor va a menos de N, y bloquea/espera cuando los valores son N == Cuenta de semáforo

  3. Contador individual con valor de 0 a N y señalización cuando el valor va a N, y bloquea/espera cuando los valores son menores que N == Semáforo de barrera (bueno, si no lo llaman, entonces deberían)

Ahora a su pregunta, cuándo usar qué. (O la versión más correcta de la pregunta.3 cuándo usar mutex y cuándo usar semáforo binario, ya que no hay comparación con el semáforo no binario.) Use mutex cuando 1. desea un comportamiento personalizado, que no se proporciona mediante semáforo binario, tales como bloqueo de giro o bloqueo rápido o bloqueos recursivos. Generalmente puede personalizar mutexes con atributos, pero personalizar el semáforo no es más que escribir un nuevo semáforo. 2. desea primitiva ligera o más rápida

Utilice semáforos, cuando lo que usted desea es exactamente proporcionado por ella.

Si no comprende lo que proporciona su implementación de semáforo binario, entonces en mi humilde opinión, use mutex.

Y, por último, lea un libro en lugar de confiar solo en SO.

5

Creo que la pregunta debería ser la diferencia entre el mutex y el semáforo binario.

Mutex = Es un mecanismo de bloqueo de propiedad, solo el hilo que adquiere el bloqueo puede liberar el bloqueo.

semáforo binario = Es más un mecanismo de señal, cualquier otro hilo de mayor prioridad si se quiere puede señalar y tomar el bloqueo.

1

Un mutex es un caso especial de semáforo. Un semáforo permite que varios hilos entren en la sección crítica. Al crear un semáforo, usted define cómo se permiten los subprocesos en la sección crítica. Por supuesto, su código debe poder manejar varios accesos a esta sección crítica.

2

Mutex es para proteger el recurso compartido.
Semaphore es para enviar los hilos.

Mutex:
Imagine que hay algunas entradas para vender. Podemos simular un caso en el que muchas personas compran los boletos al mismo tiempo: cada persona es un hilo para comprar boletos. Obviamente, necesitamos usar el mutex para proteger los tickets porque es el recurso compartido.


Semáforo:
Imaginemos que tenemos que hacer un cálculo de la siguiente manera:

c = a + b; 

Además, necesitamos una función geta() para calcular a, una función getb() para calcular b y una función getc() para hacer el cálculo c = a + b.

Obviamente, no podemos hacer el c = a + b a menos que geta() y getb() hayan sido terminados.
Si las tres funciones son tres hilos, necesitamos enviar los tres hilos.

int a, b, c; 
void geta() 
{ 
    a = calculatea(); 
    semaphore_increase(); 
} 

void getb() 
{ 
    b = calculateb(); 
    semaphore_increase(); 
} 

void getc() 
{ 
    semaphore_decrease(); 
    semaphore_decrease(); 
    c = a + b; 
} 

t1 = thread_create(geta); 
t2 = thread_create(getb); 
t3 = thread_create(getc); 
thread_join(t3); 

Con la ayuda del semáforo, el código anterior puede asegurarse de que t3 no va a hacer su trabajo hasta el t1 y t2 han hecho su trabajo.

En una palabra, semáforo es para hacer que los hilos se ejecuten como un orden logicial mientras que mutex es para proteger el recurso compartido.
Así que NO son lo mismo, aunque algunas personas siempre dicen que mutex es un semáforo especial con el valor inicial 1. Puede decirlo también, pero tenga en cuenta que se usan en diferentes casos. No reemplace uno por el otro incluso si puede hacer eso.

+0

Vender entradas es un buen ejemplo. el ejemplo del semáforo es poco claro (para mí de todos modos). – prayagupd

+1

@prayagupd El ejemplo de semáforo es para hacer subprocesos en algún orden, mientras que la venta de tickets no necesita ningún pedido. Si hay tres personas: a, b y c. Cuando vienen a comprar boletos, no nos importa la orden de comprar boletos. Sin embargo, si hacemos ese cálculo: 'x = getx(); y = gety(); z = x + y; 'Por alguna razón, usamos tres hilos para hacer las tres cosas, ahora el orden de los hilos es muy importante porque no podemos hacer' x + y' a menos que 'getx' y' gety' hayan terminado . En una palabra, el semáforo se usa cuando nos preocupa el orden de ejecución de multi-threading. – Yves

+0

te tengo. Suena similar a [barrera] (https://en.wikipedia.org/wiki/Barrier_ (computer_science)). Puedo decir que espere hasta que los hilos 'x' y' y' se hayan completado, luego calcule 'z = x + y'. Sé que Java tiene ['CyclicBarrier'] (http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CyclicBarrier.html). Además, no estoy seguro si puedo decir que 'mapreduce' también es un uso de semáforo, porque no puedo' reducir' hasta que se completen todos los 'map's. – prayagupd

0

Todas las respuestas anteriores son de buena calidad, pero éste es sólo por nombrar memorize.The objeto mutex se deriva de mutuamente excluyentes por lo tanto, te animas a pensar en un bloqueo de exclusión mutua como la exclusión mutua entre las dos como en solo uno a la vez, y si lo poseo solo puede tenerlo después de que lo libere.Por otro lado, tal caso no existe para El semáforo es como un semáforo (que también significa la palabra Semáforo) .

Cuestiones relacionadas