Módulos concurrencia y atomicos — Programación Concurrente

Archivos: stdlib/std/concurrencia.fa, stdlib/std/atomicos.fa

¿Por qué existen?

Proveen capacidades de programación concurrente en Forja. concurrencia.fa implementa hilos (hilo), canales de comunicación (canal), y la primitiva seleccionar (select). atomicos.fa proporciona operaciones atómicas para acceso compartido sin locks.

Módulo concurrencia — Hilos y Canales

FunciónDescripción
hilo_crear(funcion)Crea un nuevo hilo que ejecuta la función dada
hilo_dormir(ms)Duerme el hilo actual por milisegundos
hilo_unir(handle)Espera a que un hilo termine (join)
canal_crear()Crea un canal de comunicación (retorna (tx, rx))
canal_enviar(tx, mensaje)Envía un mensaje por el canal
canal_recibir(rx)Recibe un mensaje del canal (bloqueante)
canal_intentar_recibir(rx)Intenta recibir sin bloquear (no bloqueante)
seleccionar(rx1, rx2, ...)Espera mensajes de múltiples canales (select)

Módulo atomicos — Operaciones Atómicas

FunciónDescripción
EnteroAtomico.nuevo(valor)Crea un nuevo entero atómico
atomico.cargar()Carga el valor actual (load)
atomico.guardar(valor)Guarda un nuevo valor (store)
atomico.intercambiar(valor)Intercambia el valor atómicamente (swap)
atomico.comparar_intercambiar(esperado, nuevo)CAS (Compare-And-Swap) atómico
atomico.sumar(valor)Suma atómica (fetch_add)
atomico.restar(valor)Resta atómica (fetch_sub)

Ejemplo: Productor-Consumidor

📄 productor_consumidor.fa
importar concurrencia

variable (tx, rx) = concurrencia.canal_crear()

funcion productor() &brace;
    para (variable i = 0; i < 5; i = i + 1) &brace;
        concurrencia.canal_enviar(tx, i)
        concurrencia.hilo_dormir(100)
    }
}

funcion consumidor() &brace;
    para (variable i = 0; i < 5; i = i + 1) &brace;
        variable msg = concurrencia.canal_recibir(rx)
        escribir_linea("Recibido: " + msg)
    }
}

variable h1 = concurrencia.hilo_crear(productor)
variable h2 = concurrencia.hilo_crear(consumidor)
concurrencia.hilo_unir(h1)
concurrencia.hilo_unir(h2)

Ejemplo: Select (equivalente a select en Go)

📄 select.fa
importar concurrencia

variable (tx1, rx1) = concurrencia.canal_crear()
variable (tx2, rx2) = concurrencia.canal_crear()

// seleccionar espera mensajes de múltiples canales
variable resultado = concurrencia.seleccionar(rx1, rx2)
escribir_linea("Llegó: " + resultado)

Casos de uso

💡 Modelo CSP: Forja implementa el modelo de Comunicación Secuencial de Procesos (CSP), similar a Go y Erlang. Las comunicaciones entre hilos se hacen mediante canales, no memoria compartida.