Sobes.tech
Middle

¿Qué es un semáforo en el contexto de la programación?

sobes.tech AI

Respuesta de la IA

El semáforo es una primitiva de sincronización de hilos que controla el acceso a un recurso limitado. Mantiene un contador entero.

Operaciones principales:

  • wait() (o P / acquire): Disminuye el contador en 1. Si el contador se vuelve negativo, el hilo se bloquea hasta que otro hilo ejecute signal().
  • signal() (o V / release): Aumenta el contador en 1. Si hay hilos bloqueados, uno de ellos se desbloquea.

Tipos de semáforos:

  • Semáforo binario (mutex): El contador toma valores 0 o 1. Se usa para garantizar exclusión mutua: solo un hilo puede acceder al recurso a la vez.
  • Semáforo contador: El contador puede tomar valores desde 0 hasta N. Se usa para gestionar el acceso a un grupo de recursos con una cantidad limitada de elementos disponibles.

Ejemplo de uso en Swift para limitar la cantidad de tareas que se ejecutan simultáneamente:

// Crear un semáforo que permite hasta 3 accesos simultáneos
let semaphore = DispatchSemaphore(value: 3)

DispatchQueue.global().async {
    // Tarea 1
    semaphore.wait() // Disminuye el contador, bloquea si > 3 tareas están en ejecución
    print("Tarea 1 iniciada")
    Thread.sleep(forTimeInterval: 2) // Simulación de trabajo
    print("Tarea 1 finalizada")
    semaphore.signal() // Aumenta el contador, desbloquea tareas en espera
}

DispatchQueue.global().async {
    // Tarea 2
    semaphore.wait()
    print("Tarea 2 iniciada")
    Thread.sleep(forTimeInterval: 3)
    print("Tarea 2 finalizada")
    semaphore.signal()
}

DispatchQueue.global().async {
    // Tarea 3
    semaphore.wait()
    print("Tarea 3 iniciada")
    Thread.sleep(forTimeInterval: 1)
    print("Tarea 3 finalizada")
    semaphore.signal()
}

DispatchQueue.global().async {
    // Tarea 4 (esperará hasta que se libere un espacio)
    semaphore.wait()
    print("Tarea 4 iniciada")
    Thread.sleep(forTimeInterval: 2)
    print("Tarea 4 finalizada")
    semaphore.signal()
}

// Esperar a que terminen todas las tareas para la demostración
// En código real, usar mecanismos de espera más confiables
Thread.sleep(forTimeInterval: 5)