Mutex
mutex_new() crea un lock de exclusión mutua. mutex_lock y mutex_unlock aseguran que solo un hilo acceda al estado compartido a la vez. Sin un mutex, los incrementos concurrentes perderían actualizaciones debido a condiciones de carrera.
Código
// Mutex — protecting shared state between threads
// Mutex — proteger estado compartido entre hilos
var counter: int = 0
fn increment_task() -> int {
let m: int = mutex_new()
var i: int = 0
while i < 1000 {
mutex_lock(m)
counter = counter + 1
mutex_unlock(m)
i = i + 1
}
mutex_destroy(m)
return 0
}
fn main() -> int {
// Without a mutex, concurrent increments would lose updates.
// The mutex ensures only one thread modifies counter at a time.
let h1: int = thread_spawn(increment_task)
let h2: int = thread_spawn(increment_task)
thread_join(h1)
thread_join(h2)
print("counter: " + int_to_string(counter))
// Expected: 2000 (1000 per thread, no lost updates)
return 0
}
Salida
counter: 2000
Explicación
mutex_new() reserva un nuevo mutex y devuelve un handle opaco. Antes de acceder a la variable compartida counter, cada hilo llama a mutex_lock(m) para adquirir acceso exclusivo, y luego a mutex_unlock(m) para liberarlo.
Dos hilos incrementan el contador 1000 veces cada uno. Sin el mutex, algunos incrementos se perderían porque ambos hilos podrían leer el mismo valor simultáneamente. Con el mutex, el conteo final siempre es exactamente 2000.
Siempre llama a mutex_destroy(m) cuando el mutex ya no se necesita, para liberar recursos del sistema. En código de producción, considera envolver las secciones críticas en funciones auxiliares para asegurar que nunca se olvide el unlock.
Source: examples/by-example/57-mutex.nx