¿Hay alguna diferencia entre un semáforo binario y un mutex o son esencialmente lo mismo?
¿Hay alguna diferencia entre un semáforo binario y un mutex o son esencialmente lo mismo?
Respuestas:
NO son lo mismo. ¡Se utilizan para diferentes propósitos!
Si bien ambos tipos de semáforos tienen un estado lleno / vacío y usan la misma API, su uso es muy diferente.
Semáforos de exclusión
mutua Los semáforos de exclusión mutua se utilizan para proteger los recursos compartidos (estructura de datos, archivo, etc.).
Un semáforo Mutex es "propiedad" de la tarea que lo lleva. Si la Tarea B intenta dar un mutex actualmente en manos de la Tarea A, la llamada de la Tarea B devolverá un error y fallará.
Mutexes siempre usan la siguiente secuencia:
- SemTake - Sección crítica - SemGive
Aquí hay un ejemplo simple:
Hilo A Hilo B Tomar mutex datos de acceso ... Tome Mutex <== Bloqueará ... Dar datos de acceso Mutex <== Desbloquea ... Dar mutex
Semáforo binario El semáforo
binario aborda una pregunta totalmente diferente:
Task A Task B
... Take BinSemaphore <== wait for something
Do Something Noteworthy
Give BinSemaphore do something <== unblocks
Tenga en cuenta que con un semáforo binario, está bien que B tome el semáforo y A lo dé.
Una vez más, un semáforo binario NO está protegiendo un recurso del acceso. El acto de dar y tomar un semáforo está fundamentalmente desacoplado.
Por lo general, no tiene mucho sentido que la misma tarea sea un dar y tomar el mismo semáforo binario.
Por lo tanto, los semáforos son más adecuados para algunos problemas de sincronización como productor-consumidor.
En Windows, los semáforos binarios son más como objetos de evento que mutexes.
Mutex can be released only by thread that had acquired it
- Acabo de probar con un simple programa basado en pthread_mutex, un hilo puede desbloquear mutex bloqueado en el hilo principal
El ejemplo del inodoro es una analogía agradable:
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 le da (libera) la clave a la siguiente persona en la cola.
Oficialmente: "Los mutex se suelen usar para serializar el acceso a una sección de código entrante que no puede ejecutarse simultáneamente por más de un subproceso. Un objeto mutex solo permite un subproceso en una sección controlada, forzando a otros subprocesos 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 inodoro idénticas gratuitas. Ejemplo, digamos que tenemos cuatro baños con cerraduras y llaves idénticas. El recuento de semáforos, el recuento de llaves, se establece en 4 al principio (los cuatro inodoros son gratuitos), luego el valor del recuento disminuye a medida que entran personas. Si todos los inodoros están llenos, es decir. no quedan teclas libres, el recuento de semáforos es 0. Ahora, cuando la ecuación. una persona sale del baño, el semáforo se incrementa a 1 (una clave gratis) y se le da 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 (incrementando el semáforo). " Ref: Biblioteca de desarrolladores de Symbian
Buenos artículos sobre el tema:
De la parte 2:
El mutex es similar a los principios del semáforo binario con una diferencia significativa: el principio de propiedad. La propiedad es el concepto simple de que cuando una tarea bloquea (adquiere) un mutex solo puede desbloquearlo (liberarlo). Si una tarea intenta desbloquear un mutex que no se ha bloqueado (por lo tanto, no posee), se encuentra una condición de error y, lo más importante, el mutex no se desbloquea. Si el objeto de exclusión mutua no tiene propiedad, irrelevante de lo que se llama, no es un mutex.
Como ninguna de las respuestas anteriores aclara la confusión, aquí hay una que despejó mi confusión.
Estrictamente hablando, un mutex es un mecanismo de bloqueo utilizado para sincronizar el acceso a un recurso. Solo una tarea (puede ser un subproceso o un proceso basado en la abstracción del sistema operativo) puede adquirir el mutex. Significa que habrá propiedad asociada con mutex, y solo el propietario puede liberar el bloqueo (mutex).
El semáforo es un mecanismo de señalización (tipo de señal "He terminado, puedes continuar"). Por ejemplo, si está escuchando canciones (suponga que es una tarea) en su teléfono móvil y al mismo tiempo que su amigo lo llamó, se activará una interrupción en la que una rutina de servicio de interrupción (ISR) indicará que la tarea de procesamiento de llamadas se activará .
Su semántica de sincronización es muy diferente:
Como tal, se puede ver un mutex como un token pasado de una tarea a otra y un semáforo como semáforo en rojo ( indica a alguien que puede continuar).
A nivel teórico, no son semánticamente diferentes. Puede implementar un mutex utilizando semáforos o viceversa (vea aquí un ejemplo). En la práctica, la implementación es diferente y ofrecen servicios ligeramente diferentes.
La diferencia práctica (en términos de los servicios del sistema que los rodean) es que la implementación de un mutex tiene como objetivo ser un mecanismo de sincronización más liviano. En oracle-speak, los mutex se conocen como pestillos y los semáforos se conocen como esperas .
En el nivel más bajo, utilizan algún tipo de prueba atómica y mecanismo de ajuste . Esto lee el valor actual de una ubicación de memoria, calcula algún tipo de condicional y escribe un valor en esa ubicación en una sola instrucción que no se puede interrumpir . Esto significa que puede adquirir un mutex y probar para ver si alguien más lo tuvo antes que usted.
Una implementación típica de mutex tiene un proceso o subproceso que ejecuta la instrucción test-and-set y evalúa si algo más ha establecido el mutex. Un punto clave aquí es que no hay interacción con el planificador , por lo que no tenemos idea (y no me importa) quién ha establecido el bloqueo. Luego, renunciamos a nuestro intervalo de tiempo e intentamos nuevamente cuando la tarea se reprograma o ejecutamos un spin-lock . Un bloqueo de giro es un algoritmo como:
Count down from 5000:
i. Execute the test-and-set instruction
ii. If the mutex is clear, we have acquired it in the previous instruction
so we can exit the loop
iii. When we get to zero, give up our time slice.
Cuando terminemos de ejecutar nuestro código protegido (conocido como sección crítica ), simplemente establecemos el valor de mutex en cero o lo que sea 'claro'. Si varias tareas intentan adquirir el mutex, la siguiente tarea que se programe después de que se libere el mutex tendrá acceso al recurso. Por lo general, usaría mutexes para controlar un recurso sincronizado donde el acceso exclusivo solo es necesario por períodos muy cortos de tiempo, normalmente para actualizar una estructura de datos compartida.
Un semáforo es una estructura de datos sincronizada (típicamente usando un mutex) que tiene un conteo y algunos contenedores de llamadas del sistema que interactúan con el planificador en un poco más de profundidad que las bibliotecas mutex. Los semáforos se incrementan y disminuyen y se usan para bloquear tareas hasta que algo más esté listo. Vea el problema del productor / consumidor para un ejemplo simple de esto. Los semáforos se inicializan a algún valor: un semáforo binario es solo un caso especial en el que el semáforo se inicializa a 1. La publicación en un semáforo tiene el efecto de despertar un proceso de espera.
Un algoritmo de semáforo básico se ve así:
(somewhere in the program startup)
Initialise the semaphore to its start-up value.
Acquiring a semaphore
i. (synchronised) Attempt to decrement the semaphore value
ii. If the value would be less than zero, put the task on the tail of the list of tasks waiting on the semaphore and give up the time slice.
Posting a semaphore
i. (synchronised) Increment the semaphore value
ii. If the value is greater or equal to the amount requested in the post at the front of the queue, take that task off the queue and make it runnable.
iii. Repeat (ii) for all tasks until the posted value is exhausted or there are no more tasks waiting.
En el caso de un semáforo binario, la principal diferencia práctica entre los dos es la naturaleza de los servicios del sistema que rodean la estructura de datos real.
EDITAR: como evan ha señalado correctamente, los spinlocks ralentizarán una máquina con un solo procesador. Solo usaría un spinlock en una caja multiprocesador porque en un solo procesador el proceso que contiene el mutex nunca lo restablecerá mientras se esté ejecutando otra tarea. Los Spinlocks solo son útiles en arquitecturas multiprocesador.
futex
llamada al sistema Linux existe para ayudar a las implementaciones de mutex / semáforo de espacio de usuario de baja latencia. en.wikipedia.org/wiki/Futex ) En la ruta rápida sin contención, o si el recurso está disponible pronto, nunca tendrá la sobrecarga de Una llamada al sistema. Pero no pasa más de unos pocos microsegundos ocupados esperando (girando). Ajustar los parámetros de retroceso y espera del bucle giratorio depende del hardware y la carga de trabajo, por supuesto, pero la biblioteca estándar generalmente tiene opciones razonables.
Aunque los mutex y los semáforos se usan como primitivas de sincronización, existe una gran diferencia entre ellos. En el caso de mutex, solo el hilo que bloqueó o adquirió el mutex puede desbloquearlo. En el caso de un semáforo, un hilo que espera en un semáforo puede ser señalado por un hilo diferente. Algunos sistemas operativos admiten el uso de mutex y semáforos entre procesos. Normalmente, el uso se crea en la memoria compartida.
Mutex: Supongamos que tenemos una sección crítica que el hilo T1 quiere acceder, luego sigue los siguientes pasos. T1:
Semáforo binario: Funciona en función de la señalización de espera y señal. espere (s) disminuya el valor "s" en uno, generalmente el valor "s" se inicializa con el valor "1", la señal (es) aumenta el valor "s" en uno. si el valor "s" es 1 significa que nadie está usando la sección crítica, cuando el valor es 0 significa que la sección crítica está en uso. supongamos que el hilo T2 está usando la sección crítica y luego sigue los pasos a continuación. T2:
La principal diferencia entre el semáforo Mutex y el binario está en Mutext si el subproceso bloquea la sección crítica, entonces tiene que desbloquear la sección crítica, ningún otro subproceso puede desbloquearlo, pero en el caso del semáforo binario si un subproceso bloquea la sección crítica utilizando la función de espera (s), entonces el valor de s se convierte en "0" y nadie puede acceder a él hasta que el valor de "s" se convierta en 1, pero suponga que alguna otra llamada de hilo señala (s), luego el valor de "s" se convierte en 1 y permite que otra función use la sección crítica. por lo tanto, en el hilo de semáforo binario no tiene propiedad.
En Windows, hay dos diferencias entre mutexes y semáforos binarios:
Un mutex solo puede ser liberado por el hilo que tiene la propiedad, es decir, el hilo que anteriormente llamó a la función Esperar, (o que tomó posesión al crearlo). Un semáforo puede ser liberado por cualquier hilo.
Un hilo puede llamar a una función de espera repetidamente en un mutex sin bloquear. Sin embargo, si llama a una función de espera dos veces en un semáforo binario sin liberar el semáforo en el medio, el hilo se bloqueará.
Obviamente, usa mutex para bloquear datos en un hilo al que otro hilo accede al mismo tiempo. Asume que acabas de llamarlock()
y en el proceso de acceso a los datos. Esto significa que no espera que ningún otro hilo (u otra instancia del mismo código de hilo) acceda a los mismos datos bloqueados por el mismo mutex. Es decir, si es el mismo código de subproceso que se ejecuta en una instancia de subproceso diferente, golpea el bloqueo, entonces ellock()
debería bloquear el flujo de control allí. Esto se aplica a un subproceso que utiliza un código de subproceso diferente, que también está accediendo a los mismos datos y que también está bloqueado por el mismo mutex. En este caso, todavía está en el proceso de acceder a los datos y puede tomar, por ejemplo, otros 15 segundos para alcanzar el desbloqueo de mutex (para que el otro hilo que se bloquea en el bloqueo de mutex se desbloquee y permita que el control acceder a los datos). ¿A cualquier costo permite que otro hilo simplemente desbloquee el mismo mutex y, a su vez, permita que el hilo que ya está esperando (bloqueando) en el bloqueo de mutex se desbloquee y acceda a los datos? ¿Espero que hayas entendido lo que digo aquí? Según lo acordado, definición universal!
Por lo tanto, si usted es muy particular sobre el uso de semáforos binarios en lugar de mutex, entonces debe tener mucho cuidado al "determinar" los bloqueos y desbloqueos. Quiero decir que cada flujo de control que golpea cada bloqueo debe golpear una llamada de desbloqueo, también no debe haber ningún "primer desbloqueo", sino que siempre debe ser "primer bloqueo".
Los mutex se utilizan para "mecanismos de bloqueo". un proceso a la vez puede usar un recurso compartido
mientras
Los semáforos se usan para "Mecanismos de señalización" como "Ya terminé, ahora puede continuar"
Mito:
Un par de artículos dice que "el semáforo binario y el mutex son iguales" o "el semáforo con el valor 1 es mutex", pero la diferencia básica es que Mutex solo puede liberarse mediante un hilo que lo haya adquirido, mientras que puede señalar el semáforo desde cualquier otro hilo
Puntos clave:
• Un subproceso puede adquirir más de un bloqueo (Mutex).
• Un mutex se puede bloquear más de una vez solo si es un mutex recursivo, aquí el bloqueo y desbloqueo para mutex debe ser el mismo
• Si un hilo que ya había bloqueado un mutex, intenta bloquear el mutex nuevamente, entrará en la lista de espera de ese mutex, lo que resulta en un punto muerto.
• El semáforo binario y el mutex son similares pero no iguales.
• Mutex es una operación costosa debido a los protocolos de protección asociados.
• El objetivo principal de mutex es lograr el acceso atómico o bloquear el recurso
Un Mutex controla el acceso a un único recurso compartido. Proporciona operaciones para adquirir () acceso a ese recurso y liberarlo () cuando haya terminado.
Un semáforo controla el acceso a un grupo compartido de recursos. Proporciona operaciones a Wait () hasta que uno de los recursos del grupo esté disponible, y Signal () cuando se devuelve al grupo.
Cuando el número de recursos que protege un semáforo es mayor que 1, se llama semáforo de conteo . Cuando controla un recurso, se llama un semáforo booleano . Un semáforo booleano es equivalente a un mutex.
Por lo tanto, un semáforo es un nivel de abstracción más alto que Mutex. Un Mutex se puede implementar usando un semáforo pero no al revés.
La pregunta modificada es: ¿Cuál es la diferencia entre un mutex y un semáforo "binario" en "Linux"?
Respuesta: Las siguientes son las diferencias: i) Alcance: el alcance de mutex está dentro de un espacio de direcciones de proceso que lo ha creado y se utiliza para la sincronización de subprocesos. Mientras que el semáforo se puede usar en todo el espacio del proceso y, por lo tanto, se puede usar para la sincronización entre procesos.
ii) Mutex es ligero y más rápido que el semáforo. Futex es aún más rápido.
iii) Mutex puede ser adquirido por el mismo subproceso con éxito varias veces con la condición de que lo libere el mismo número de veces. Se bloqueará otro hilo que intente adquirir. Mientras que en caso de semáforo, si el mismo proceso intenta adquirirlo nuevamente, se bloquea, ya que solo se puede adquirir una vez.
Diferencia entre semáforo binario y mutex: PROPIEDAD: los semáforos se pueden señalar (publicar) incluso desde un propietario no actual. Significa que puedes simplemente publicar desde cualquier otro hilo, aunque no eres el propietario.
El semáforo es una propiedad pública en proceso, simplemente puede ser publicado por un hilo no propietario. Marque esta diferencia en negrita, significa mucho.
Mutex trabaja en el bloqueo de la región crítica, pero Semaphore trabaja en la cuenta.
http://www.geeksforgeeks.org/archives/9102 discute en detalles.
Mutex
es un mecanismo de bloqueo utilizado para sincronizar el acceso a un recurso.
Semaphore
Es un mecanismo de señalización.
Depende del programador si él / ella quiere usar el semáforo binario en lugar de mutex.
Además del hecho de que los mutexes tienen un propietario, los dos objetos pueden optimizarse para un uso diferente. Los mutexes están diseñados para mantenerse solo por un corto tiempo; violar esto puede causar un bajo rendimiento y una programación injusta. Por ejemplo, se puede permitir que un hilo en ejecución adquiera un mutex, aunque otro hilo ya esté bloqueado en él. Los semáforos pueden proporcionar más justicia, o la justicia puede ser forzada usando varias variables de condición.
sem_post()
para SCHED_FIFO
y SCHED_RR
(ambos de estos no están por defecto): la más alta prioridad de hilo, y si hay múltiples con la misma prioridad, el hilo que ha estado esperando más tiempo. OpenSolaris sigue esta regla FIFO hasta cierto punto incluso para la programación normal. Para glibc y FreeBSD, desbloquear un mutex simple (es decir, no proteger con prioridad o heredar con prioridad) y publicar un semáforo son básicamente lo mismo, marcar el objeto como desbloqueado y luego, si puede haber hilos en espera, llamar al núcleo para que active uno.
En windows la diferencia es la siguiente. MUTEX: el proceso que ejecuta con éxito la espera tiene que ejecutar una señal y viceversa. SEMÁFOROS BINARIOS: diferentes procesos pueden ejecutar la operación de espera o señal en un semáforo.
Mientras que un semáforo binario se puede usar como un mutex, un mutex es un caso de uso más específico, ya que solo el proceso que bloqueó el mutex se supone que lo desbloquea. Esta restricción de propiedad hace posible proporcionar protección contra:
Estas restricciones no siempre están presentes porque degradan la velocidad. Durante el desarrollo de su código, puede habilitar estas comprobaciones temporalmente.
por ejemplo, puede habilitar el atributo de comprobación de errores en su mutex. Se produce un error al volver a comprobar los mutexes EDEADLK
si intentas bloquear el mismo dos veces y EPERM
si desbloqueas un mutex que no es tuyo.
pthread_mutex_t mutex;
pthread_mutexattr_t attr;
pthread_mutexattr_init (&attr);
pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
pthread_mutex_init (&mutex, &attr);
Una vez inicializado, podemos colocar estos controles en nuestro código de esta manera:
if(pthread_mutex_unlock(&mutex)==EPERM)
printf("Unlock failed:Mutex not owned by this thread\n");
El concepto fue claro para mí después de repasar las publicaciones anteriores. Pero había algunas preguntas persistentes. Entonces, escribí este pequeño fragmento de código.
Cuando tratamos de dar un semáforo sin tomarlo, pasa. Pero, cuando intenta dar un mutex sin tomarlo, falla. Probé esto en una plataforma Windows. Habilite USE_MUTEX para ejecutar el mismo código usando un MUTEX.
#include <stdio.h>
#include <windows.h>
#define xUSE_MUTEX 1
#define MAX_SEM_COUNT 1
DWORD WINAPI Thread_no_1( LPVOID lpParam );
DWORD WINAPI Thread_no_2( LPVOID lpParam );
HANDLE Handle_Of_Thread_1 = 0;
HANDLE Handle_Of_Thread_2 = 0;
int Data_Of_Thread_1 = 1;
int Data_Of_Thread_2 = 2;
HANDLE ghMutex = NULL;
HANDLE ghSemaphore = NULL;
int main(void)
{
#ifdef USE_MUTEX
ghMutex = CreateMutex( NULL, FALSE, NULL);
if (ghMutex == NULL)
{
printf("CreateMutex error: %d\n", GetLastError());
return 1;
}
#else
// Create a semaphore with initial and max counts of MAX_SEM_COUNT
ghSemaphore = CreateSemaphore(NULL,MAX_SEM_COUNT,MAX_SEM_COUNT,NULL);
if (ghSemaphore == NULL)
{
printf("CreateSemaphore error: %d\n", GetLastError());
return 1;
}
#endif
// Create thread 1.
Handle_Of_Thread_1 = CreateThread( NULL, 0,Thread_no_1, &Data_Of_Thread_1, 0, NULL);
if ( Handle_Of_Thread_1 == NULL)
{
printf("Create first thread problem \n");
return 1;
}
/* sleep for 5 seconds **/
Sleep(5 * 1000);
/*Create thread 2 */
Handle_Of_Thread_2 = CreateThread( NULL, 0,Thread_no_2, &Data_Of_Thread_2, 0, NULL);
if ( Handle_Of_Thread_2 == NULL)
{
printf("Create second thread problem \n");
return 1;
}
// Sleep for 20 seconds
Sleep(20 * 1000);
printf("Out of the program \n");
return 0;
}
int my_critical_section_code(HANDLE thread_handle)
{
#ifdef USE_MUTEX
if(thread_handle == Handle_Of_Thread_1)
{
/* get the lock */
WaitForSingleObject(ghMutex, INFINITE);
printf("Thread 1 holding the mutex \n");
}
#else
/* get the semaphore */
if(thread_handle == Handle_Of_Thread_1)
{
WaitForSingleObject(ghSemaphore, INFINITE);
printf("Thread 1 holding semaphore \n");
}
#endif
if(thread_handle == Handle_Of_Thread_1)
{
/* sleep for 10 seconds */
Sleep(10 * 1000);
#ifdef USE_MUTEX
printf("Thread 1 about to release mutex \n");
#else
printf("Thread 1 about to release semaphore \n");
#endif
}
else
{
/* sleep for 3 secconds */
Sleep(3 * 1000);
}
#ifdef USE_MUTEX
/* release the lock*/
if(!ReleaseMutex(ghMutex))
{
printf("Release Mutex error in thread %d: error # %d\n", (thread_handle == Handle_Of_Thread_1 ? 1:2),GetLastError());
}
#else
if (!ReleaseSemaphore(ghSemaphore,1,NULL) )
{
printf("ReleaseSemaphore error in thread %d: error # %d\n",(thread_handle == Handle_Of_Thread_1 ? 1:2), GetLastError());
}
#endif
return 0;
}
DWORD WINAPI Thread_no_1( LPVOID lpParam )
{
my_critical_section_code(Handle_Of_Thread_1);
return 0;
}
DWORD WINAPI Thread_no_2( LPVOID lpParam )
{
my_critical_section_code(Handle_Of_Thread_2);
return 0;
}
El hecho mismo de que el semáforo le permite señalar "se hace usando un recurso", aunque nunca haya sido propietario del recurso, me hace pensar que existe un acoplamiento muy flojo entre la posesión y la señalización en el caso de los semáforos.
Mutex se usa para proteger el código y los datos confidenciales, el semáforo se usa para la sincronización. También puede tener un uso práctico para proteger el código sensible, pero puede existir el riesgo de liberar la protección por el otro hilo por la operación V. la diferencia entre bi-semáforo y mutex es la propiedad. Por ejemplo, por inodoro, Mutex es como que uno puede entrar al inodoro y cerrar la puerta, nadie más puede entrar hasta que el hombre salga, el bi-semáforo es como que uno puede entrar el inodoro y cerrar la puerta, pero alguien más podría entrar pidiéndole al administrador que abra la puerta, es ridículo.
Mutex
Los mutex generalmente se usan para serializar el acceso a una sección de código entrante que no puede ejecutarse simultáneamente por más de un subproceso. Un objeto mutex solo permite un subproceso en una sección controlada, lo que obliga a otros subprocesos que intentan obtener acceso a esa sección a esperar hasta que el primer subproceso haya salido de esa sección. El uso correcto de un mutex es proteger un recurso compartido puede tener un peligro efecto secundario no deseado Cualquiera de las dos tareas RTOS que operan con diferentes prioridades y se coordinan a través de un mutex, crean la oportunidad para la inversión de prioridad . Mutex funciona en el espacio del usuario .
Semáforo
El semáforo es un mecanismo de señalización. Semaphore 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 (incrementando el semáforo). Permite que varios hilos accedan a recursos compartidos. El uso correcto de un semáforo es para señalizar de una tarea a otra. Los semáforos también se pueden usar para señalar desde una rutina de servicio de interrupción (ISR) a una tarea. La señalización de un semáforo es un comportamiento RTOS sin bloqueo y, por lo tanto, ISR seguro. Debido a que esta técnica elimina la necesidad propensa a errores de deshabilitar las interrupciones a nivel de tarea, esto funciona en el espacio del kernel .
La respuesta puede depender del sistema operativo de destino. Por ejemplo, al menos una implementación de RTOS con la que estoy familiarizado permitirá múltiples operaciones secuenciales de "obtención" contra un único mutex del sistema operativo, siempre que estén todas dentro del mismo contexto de subproceso. Los múltiples get deben ser reemplazados por un número igual de puestos antes de que otro hilo pueda obtener el mutex. Esto difiere de los semáforos binarios, para los cuales solo se permite un solo get a la vez, independientemente de los contextos de subprocesos.
La idea detrás de este tipo de mutex es que proteja un objeto al permitir que un solo contexto modifique los datos a la vez. Incluso si el subproceso obtiene el mutex y luego llama a una función que modifica aún más el objeto (y obtiene / coloca el mutex protector alrededor de sus propias operaciones), las operaciones aún deberían ser seguras porque todas ocurren bajo un solo subproceso.
{
mutexGet(); // Other threads can no longer get the mutex.
// Make changes to the protected object.
// ...
objectModify(); // Also gets/puts the mutex. Only allowed from this thread context.
// Make more changes to the protected object.
// ...
mutexPut(); // Finally allows other threads to get the mutex.
}
Por supuesto, cuando use esta función, debe estar seguro de que todos los accesos dentro de un solo hilo son realmente seguros.
No estoy seguro de cuán común es este enfoque, o si se aplica fuera de los sistemas con los que estoy familiarizado. Para ver un ejemplo de este tipo de mutex, consulte ThreadX RTOS.
Los mutexes tienen propiedad, a diferencia de los semáforos. Aunque cualquier hilo, dentro del alcance de un mutex, puede obtener un mutex desbloqueado y bloquear el acceso a la misma sección crítica de código, solo el hilo que bloqueó un mutex debe desbloquearlo .
Como muchas personas aquí han mencionado, se usa un mutex para proteger una pieza crítica de código (también conocida como sección crítica). Adquirirá el mutex (bloqueo), ingresará a la sección crítica y liberará mutex (desbloqueo) todo en el mismo hilo .
Mientras usa un semáforo, puede hacer que un hilo espere en un semáforo (digamos el hilo A), hasta que otro hilo (digamos el hilo B) complete cualquier tarea, y luego configure el semáforo para el hilo A para detener la espera y continuar su tarea.
Mejor solución
La unica diferencia es
1.Mutex -> bloquear y desbloquear son propiedad de un hilo que bloquea el mutex.
2. Semáforo -> Sin propiedad, es decir; Si un hilo llama a semwait (s), cualquier otro hilo puede llamar a sempost (s) para eliminar el bloqueo.
MUTEX
Hasta hace poco, el único candado para dormir en el núcleo era el semáforo. La mayoría de los usuarios de semáforos instanciaron un semáforo con un recuento de uno y los trataron como un bloqueo de exclusión mutua, una versión inactiva del bloqueo de giro. Desafortunadamente, los semáforos son bastante genéricos y no imponen ninguna restricción de uso. Esto los hace útiles para administrar el acceso exclusivo en situaciones oscuras, como bailes complicados entre el núcleo y el espacio de usuario. Pero también significa que un bloqueo más simple es más difícil de hacer, y la falta de reglas forzadas hace imposible cualquier tipo de depuración automática o aplicación de restricciones. Buscando un bloqueo para dormir más simple, los desarrolladores del kernel introdujeron el mutex. Sí, como está acostumbrado, ese es un nombre confuso. Vamos a aclararlo. El término "mutex" es un nombre genérico para referirse a cualquier candado para dormir que obliga a la exclusión mutua, como un semáforo con un recuento de uso de uno. En los núcleos de Linux recientes, el nombre propio "mutex" ahora también es un tipo específico de bloqueo de suspensión que implementa la exclusión mutua. Es decir, un mutex es un mutex.
La simplicidad y la eficiencia del mutex provienen de las restricciones adicionales que impone a sus usuarios más allá de lo que requiere el semáforo. A diferencia de un semáforo, que implementa el comportamiento más básico de acuerdo con el diseño original de Dijkstra, el mutex tiene un caso de uso más estricto y estrecho: n Solo una tarea puede contener el mutex a la vez. Es decir, el recuento de uso en un mutex es siempre uno.
[1] Desarrollo del kernel de Linux, tercera edición Robert Love
Creo que la mayoría de las respuestas aquí fueron confusas, especialmente aquellas que dicen que mutex solo puede liberarse mediante el proceso que lo contiene, pero el semáforo puede señalarse mediante un proceso. La línea anterior es un poco vaga en términos de semáforo. Para entenderlo, debemos saber que hay dos tipos de semáforos, uno se llama semáforo de conteo y el otro se llama semáforo binario. Al contar, el semáforo maneja el acceso a n número de recursos donde n puede definirse antes del uso. Cada semáforo tiene una variable de recuento, que mantiene el recuento de la cantidad de recursos en uso, inicialmente, se establece en n. Cada proceso que desea utilizar un recurso realiza una operación wait () en el semáforo (disminuyendo así el recuento). Cuando un proceso libera un recurso, realiza una operación release () (incrementando el conteo). Cuando el recuento se convierte en 0, Se están utilizando todos los recursos. Después de eso, el proceso espera hasta que el recuento sea más de 0. Ahora aquí está la captura, solo el proceso que contiene el recurso puede aumentar el recuento, ningún otro proceso puede aumentar el recuento, solo los procesos que contienen un recurso pueden aumentar el recuento y el proceso esperar el semáforo nuevamente verifica y cuando ve el recurso disponible, disminuye el conteo nuevamente. Entonces, en términos de semáforo binario, solo el proceso que contiene el semáforo puede aumentar el recuento, y el recuento permanece en cero hasta que deja de usar el semáforo y aumenta el recuento y otros procesos tienen la oportunidad de acceder al semáforo. Ahora aquí está la captura, solo el proceso que contiene el recurso puede aumentar el recuento, ningún otro proceso puede aumentar el recuento, solo los procesos que retienen un recurso pueden aumentar el recuento y el proceso que espera el semáforo nuevamente verifica y cuando ve que el recurso está disponible Disminuye la cuenta de nuevo. Entonces, en términos de semáforo binario, solo el proceso que contiene el semáforo puede aumentar el recuento, y el recuento permanece en cero hasta que deja de usar el semáforo y aumenta el recuento y otros procesos tienen la oportunidad de acceder al semáforo. Ahora aquí está la captura, solo el proceso que contiene el recurso puede aumentar el recuento, ningún otro proceso puede aumentar el recuento, solo los procesos que contienen un recurso pueden aumentar el recuento y el proceso que espera el semáforo vuelve a verificar y cuando ve que el recurso está disponible, Disminuye la cuenta de nuevo. Entonces, en términos de semáforo binario, solo el proceso que contiene el semáforo puede aumentar el recuento, y el recuento permanece en cero hasta que deja de usar el semáforo y aumenta el recuento y otros procesos tienen la oportunidad de acceder al semáforo.
La principal diferencia entre el semáforo binario y el mutex es que el semáforo es un mecanismo de señalización y el mutex es un mecanismo de bloqueo, pero el semáforo binario parece funcionar como un mutex que crea confusión, pero ambos son conceptos diferentes adecuados para diferentes tipos de trabajo.