Semáforo
Un Semaphore de std/sync limita el número de accesos concurrentes a un recurso. sem_new(n) crea un semáforo con n permisos, sem_acquire toma un permiso (bloqueando si no hay ninguno disponible), y sem_release devuelve uno.
Código
// Semaphore — limiting concurrent access to a resource
// Semáforo — limitar acceso concurrente a un recurso
import "std/sync"
var sem: Semaphore = sem_new(2)
var done: WaitGroup = wg_new()
fn access_resource() -> int {
sem_acquire(sem)
print("acquired (count: " + int_to_string(sem_count(sem)) + ")")
sleep(50)
sem_release(sem)
print("released")
wg_done(done)
return 0
}
fn main() -> int {
// Allow at most 2 concurrent accesses
wg_add(done, 5)
var i: int = 0
while i < 5 {
thread_spawn(access_resource)
i = i + 1
}
wg_wait(done)
print("all done")
return 0
}
Salida
acquired (count: 1) acquired (count: 0) released released acquired (count: 1) acquired (count: 0) released released acquired (count: 1) released all done
Explicación
sem_new(2) crea un semáforo con 2 permisos. Como máximo 2 hilos pueden tener un permiso al mismo tiempo. Cuando un tercer hilo llama a sem_acquire, se bloquea hasta que uno de los dos primeros llame a sem_release.
Cinco hilos compiten por el semáforo. sem_count devuelve el número de permisos restantes, que cae a 0 cuando ambos están tomados. Después de dormir 50ms (simulando trabajo), cada hilo libera su permiso y avisa al WaitGroup.
Este patrón es útil para limitar la velocidad de acceso a recursos externos como conexiones de base de datos, descriptores de archivo o endpoints de API, donde se desea concurrencia controlada en lugar de exclusión mutua total.