¿Cuándo deberíamos usar mutex y cuándo deberíamos usar semáforo?
linux
multithreading
synchronization
mutex
semaphore
Karthik Balaguru
fuente
fuente
Respuestas:
Así es como recuerdo cuándo usar qué:
Semáforo: use un semáforo cuando (hilo) quiera dormir hasta que otro hilo le indique que se despierte. El semáforo 'abajo' ocurre en un hilo (productor) y el semáforo 'arriba' (para el mismo semáforo) ocurre en otro hilo (consumidor) por ejemplo: En un problema productor-consumidor, el productor quiere dormir hasta que al menos una ranura del búfer esté vacía, solo el hilo del consumidor puede saber cuándo una ranura de búfer está vacía.
Mutex: Use un mutex cuando (hilo) desee ejecutar código que no debería ser ejecutado por ningún otro hilo al mismo tiempo. Mutex 'down' ocurre en un hilo y mutex 'up' debe ocurrir en el mismo hilo más adelante. Por ejemplo: si está eliminando un nodo de una lista vinculada global, no desea que otro hilo se entretenga con punteros mientras elimina el nodo. Cuando adquiere un mutex y está ocupado eliminando un nodo, si otro hilo intenta adquirir el mismo mutex, se pondrá en 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 interrupciones dentro del núcleo del sistema operativo nunca debe dormir. Si lo hace, el sistema se congelará / bloqueará. Si necesita insertar un nodo en la lista vinculada compartida globalmente desde el controlador de interrupciones, adquiera un spinlock - insert node - release spinlock.
fuente
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 conteo de uno) y el requisito de que solo puede ser liberado por el mismo hilo que lo bloqueó (a) .
Un semáforo, por otro lado, tiene un recuento arbitrario y puede ser bloqueado por tantos casilleros al mismo tiempo. Y puede que no tenga el requisito de ser liberado por el mismo hilo que lo reclamó (pero, si no es así, debe rastrear cuidadosamente quién tiene actualmente la responsabilidad de ello, al igual que la memoria asignada).
Por lo tanto, si tiene varias instancias de un recurso (por ejemplo, tres unidades de cinta), podría usar un semáforo con un recuento de 3. Tenga en cuenta que esto no le dice cuál de esas unidades de cinta tiene, solo que tiene un cierto número.
También con los 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 quiere corromper), un mutex es más adecuado.
Las operaciones equivalentes son:
Aparte: en caso de que alguna vez se haya preguntado por las letras extrañas que se usan para reclamar y lanzar semáforos, es porque el inventor era holandés. Probeer te verlagen significa intentar disminuir mientras que verhogen significa aumentar.
(a) ... o se puede pensar en algo totalmente distinto de un semáforo, que puede ser más seguro dados sus usos casi siempre diferentes.
fuente
¡Es muy importante entender que un mutex no es un semáforo con cuenta 1!
Esta es la razón por la que hay cosas como semáforos binarios (que en realidad son semáforos con cuenta 1).
La diferencia entre un mutex y un semáforo binario es el principio de propiedad:
Un mutex es adquirido por una tarea y por lo tanto también debe ser liberado por la misma tarea. Esto hace posible solucionar varios problemas con semáforos binarios (liberació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.
Debido a que el mutex debe 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.
Entonces, mi recomendación es: si tiene mutexes implementados limpiamente y variables de condición (como con los pthreads POSIX), use estos.
Use semáforos solo si se ajustan exactamente al problema que está tratando de resolver, no intente construir otras primitivas (por ejemplo, rw-locks fuera de los semáforos, use mutex y variables de condición para estos)
Hay muchos malentendidos mutex y semáforos. La mejor explicación que encontré hasta ahora está en este artículo de 3 partes:
Mutex vs.Semaphores - Parte 1: Semáforos
Mutex frente a semáforos - Parte 2: El mutex
Mutex vs semáforos - Parte 3 (parte final): Problemas de exclusión mutua
fuente
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 de la ejecución simultánea, los semáforos se usan para que un hilo indique que se ejecute otro hilo.
El escenario del semáforo es diferente:
Consulte http://www.netrino.com/node/202 para obtener más explicaciones.
fuente
sema_wait
:-) En mi opinión, ambos se tratan de recursos y la notificación entregada a otros hilos es un efecto secundario (muy importante, en cuanto al rendimiento) del proteccion.You say that the usage pattern of semaphores is to notify threads
Un punto sobre la notificación de hilos. Puede llamarsem_post
desde un manejador de señales de manera segura ( pubs.opengroup.org/onlinepubs/009695399/functions/… ) pero no se recomienda llamarpthread_mutex_lock
ypthread_mutex_unlock
desde manejadores de señales ( manpages.ubuntu.com/manpages/lucid/man3/… )Consulte "El ejemplo del inodoro" - http://pheatt.emporia.edu/courses/2010/cs557f10/hand07/Mutex%20vs_%20Semaphore.htm :
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 entrega (libera) la llave a la siguiente persona en la cola.
Oficialmente: "Los mutex se utilizan normalmente para serializar el acceso a una sección de código reentrante que no puede ser ejecutado simultáneamente por más de un hilo. Un objeto mutex solo permite que un hilo entre en una sección controlada, lo que obliga a otros hilos que intentan obtener acceso a esa sección para esperar hasta que el primer hilo haya salido de esa sección ". Ref: Biblioteca de desarrolladores de Symbian
(Un mutex es realmente un semáforo con valor 1.)
Semáforo:
Es el número de llaves de baño idénticas y gratuitas. Por ejemplo, digamos que tenemos cuatro baños con cerraduras y llaves idénticas. El recuento del semáforo, el recuento de llaves, se establece en 4 al principio (los cuatro inodoros son gratuitos), luego el valor del recuento disminuye a medida que las personas entran. Si todos los inodoros están llenos, es decir. no quedan claves libres, el recuento de semáforos es 0. Ahora, cuando eq. una persona sale del baño, el semáforo se aumenta a 1 (una tecla libre) y se entrega a la siguiente persona en la cola.
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 (disminuyendo el semáforo) y pueden indicar que han terminado de usar el recurso (aumentando el semáforo). " Ref: Biblioteca de desarrolladores de Symbian
fuente
Intento no sonar loco, pero no puedo evitarlo.
Su pregunta debería ser ¿cuál es la diferencia entre mutex y semáforos? Y para ser más precisos, la pregunta debería ser, '¿cuál es la relación entre mutex y semáforos?'
(Habría agregado esa pregunta, pero estoy 100% seguro de que algún moderador demasiado entusiasta la cerraría como duplicada sin entender la diferencia entre diferencia y relación).
En terminología de objetos podemos observar que:
observación.1 El semáforo contiene mutex
observación.2 El 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 NO son mutex.
Hay un ingrediente especial llamado Señalización (posix usa condition_variable para ese nombre), requerido para hacer un semáforo a partir de mutex. Piense en ello como una fuente de notificación. Si dos o más hilos están suscritos a la misma fuente de notificación, entonces es posible enviarles un mensaje a UNO o a TODOS, para despertar.
Podría 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 derrama como lluvia monzónica.
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). El 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ñalar puede hacer un tipo de semáforo.
Contador único con valor 0 o 1 y señalización cuando el valor pasa a 1 Y luego desbloquea a uno de los tipos que esperan la señal == Semáforo binario
Contador único con valor de 0 a N y que indica cuando el valor desciende por debajo de N, y se bloquea / espera cuando los valores son N == Semáforo de recuento
Contador único con valor de 0 a N y que indica cuando el valor pasa a N, y se bloquea / espera cuando los valores son inferiores a N == Semáforo de barrera (bueno, si no lo llaman, entonces deberían hacerlo).
Ahora a su pregunta, cuándo usar qué. (O en lugar de corregir la versión de la pregunta.3 cuándo usar mutex y cuándo usar binary-semáforo, ya que no hay comparación con el semáforo no binario.) Use mutex cuando 1. desee un comportamiento personalizado, que no sea proporcionado por binary semáforo, tales como bloqueo de giro o bloqueo rápido o bloqueos recursivos. Por lo general, puede personalizar los mutex con atributos, pero personalizar el semáforo no es más que escribir un nuevo semáforo. 2. quieres un primitivo ligero o más rápido
Utilice semáforos, cuando lo que desea se lo proporciona exactamente.
Si no comprende lo que proporciona su implementación de binary-semaphore, en mi humilde opinión, use mutex.
Y, por último, lea un libro en lugar de confiar solo en SO.
fuente
Creo que la pregunta debería ser la diferencia entre mutex y semáforo binario.
Mutex = Es un mecanismo de bloqueo de propiedad, solo el hilo que adquiere el bloqueo puede liberarlo.
binary Semaphore = Es más un mecanismo de señal, cualquier otro hilo de mayor prioridad si lo desea puede señalar y tomar el bloqueo.
fuente
Mutex es para proteger el recurso compartido.
El semáforo es enviar los hilos.
Mutex:
Imagina que hay algunas entradas para vender. Podemos simular un caso en el que muchas personas compran las entradas al mismo tiempo: cada persona es un hilo para comprar entradas. Obviamente, necesitamos usar el mutex para proteger los tickets porque es el recurso compartido.
Semáforo:
Imagine que necesitamos hacer un cálculo como se muestra a continuación:
Además, necesitamos una función
geta()
para calculara
, una funcióngetb()
para calcularb
y una funcióngetc()
para hacer el cálculoc = a + b
.Obviamente, no podemos hacer el a
c = a + b
menos quegeta()
ygetb()
haya terminado.Si las tres funciones son tres subprocesos, necesitamos distribuir los tres subprocesos.
Con la ayuda del semáforo, el código anterior puede asegurarse de que
t3
no va a hacer su trabajo hasta elt1
yt2
han hecho su trabajo.En una palabra, semáforo es hacer que los hilos se ejecuten como un orden lógico, mientras que mutex es para proteger el recurso compartido.
Entonces NO son lo mismo incluso si algunas personas siempre dicen que mutex es un semáforo especial con el valor inicial 1. También puede decir esto, pero tenga en cuenta que se usan en diferentes casos. No reemplace uno por otro incluso si puede hacerlo.
fuente
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 hacerlo ax + y
menos quegetx
ygety
hayamos terminado. En una palabra, el semáforo se usa cuando nos preocupamos por el orden de ejecución de los subprocesos múltiples.x
yy
se completen, luego calculez = x + y
. Sé que Java tieneCyclicBarrier
. Además, no estoy seguro de poder decir quemapreduce
es un caso de uso de semáforo también, porque no puedoreduce
hasta quemap
se completen todos los correos electrónicos .Todas las respuestas anteriores son de buena calidad, pero esta es solo para memorizar. El nombre Mutex se deriva de Mutuamente Exclusivo, por lo que está motivado a pensar en un bloqueo de mutex como Exclusión Mutua entre dos como en uno solo a la vez, y si yo Lo poseyó, puede tenerlo solo después de que lo suelte. Por otro lado, tal caso no existe porque Semaphore es como una señal de tráfico (que la palabra Semaphore también significa).
fuente
Como se señaló, un semáforo con una cuenta de uno es lo mismo que un semáforo 'binario', que es lo mismo que un mutex.
Las principales cosas que he visto para los semáforos con un recuento mayor que uno usado son situaciones de productor / consumidor en las que tienes una cola de un cierto tamaño fijo.
Entonces tienes dos semáforos. El primer semáforo se establece inicialmente para que sea 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, 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 el primero.
De esta forma, el productor se bloquea siempre que llena la cola y el consumidor se bloquea cuando la cola está vacía.
fuente
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, 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.
fuente
El semáforo binario y Mutex son diferentes. Desde la perspectiva del sistema operativo, un semáforo binario y un semáforo de conteo se implementan de la misma manera y un semáforo binario puede tener un valor de 0 o 1.
Mutex -> Solo se puede usar para un solo propósito de exclusión mutua para una sección crítica del código.
Semáforo -> Puede usarse para resolver una variedad de problemas. Se puede utilizar un semáforo binario para la señalización y también resolver el problema de exclusión mutua. Cuando se inicializa a 0 , resuelve el problema de señalización y cuando se inicializa a 1 , resuelve el problema de exclusión mutua .
Cuando la cantidad de recursos es mayor y es necesario sincronizar, podemos usar el semáforo de conteo.
En mi blog, he discutido estos temas en detalle.
https://designpatterns-oo-cplusplus.blogspot.com/2015/07/synchronization-primitives-mutex-and.html
fuente