¿Cuál es la diferencia entre un semáforo y un mutex?
sobes.tech AI
Respuesta de la IA
El semáforo es un mecanismo de sincronización generalizado utilizado para gestionar el acceso a recursos limitados por múltiples hilos competidores. Mantiene un valor entero que disminuye al adquirir el recurso y aumenta al liberarlo. Si el valor del semáforo es cero, el intento de adquirirlo bloquea el hilo hasta que otro hilo libere el recurso. Puede usarse para limitar la cantidad de hilos que trabajan simultáneamente.
El mutex (exclusión mutua) es un semáforo binario que puede estar en estado bloqueado o desbloqueado. Se usa para proteger secciones críticas del código contra accesos simultáneos por varios hilos. Solo un hilo puede adquirir el mutex en un momento dado. El hilo que ha adquirido el mutex no puede ser interrumpido por otro hilo que intente adquirirlo. Si se intenta adquirir un mutex bloqueado, el hilo se bloqueará hasta que se libere.
Diferencias clave:
| Característica | Semáforo | Mutex |
|---|---|---|
| Tipo | Mecanismo de sincronización generalizado | Semáforo binario (caso particular de semáforo) |
| Valor | Entero (>= 0) | Binario (0 o 1) |
| Propósito | Control de acceso a recursos, limitación de hilos | Protección de secciones críticas, exclusión mutua |
| Propietario | Puede no tener propietario | Siempre tiene propietario (hilo que lo adquirió) |
| Uso en iOS | DispatchSemaphore |
Frecuentemente implementado mediante DispatchQueue.sync o NSRecursiveLock en algunos escenarios |
Ejemplo de uso de mutex para proteger una sección crítica:
// En el contexto de GCD (Grand Central Dispatch)
let serialQueue = DispatchQueue(label: "com.example.criticalSection")
serialQueue.sync {
// Sección crítica del código
// Solo un hilo puede estar aquí en cualquier momento
}
Ejemplo de uso de semáforo para limitar tareas en paralelo:
// En el contexto de GCD (Grand Central Dispatch)
let semaphore = DispatchSemaphore(value: 3) // Permitimos 3 tareas en paralelo
DispatchQueue.global().async {
semaphore.wait() // Disminuye el valor del semáforo en 1. Bloquea si el valor es 0.
// Código de la tarea en paralelo
print("Tarea en ejecución")
Thread.sleep(forTimeInterval: 1) // Simulación de trabajo
semaphore.signal() // Aumenta el valor del semáforo en 1. Desbloquea el hilo en espera, si lo hay.
print("Tarea finalizada")
}
// Se pueden lanzar varios bloques así. Solo 3 se ejecutarán simultáneamente.