Sobes.tech
Middle

¿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.