Productor-Consumidor
El patrón productor-consumidor desacopla la generación de datos de su procesamiento. El canal acotado (capacidad 3) provee contrapresión natural: el productor se bloquea cuando el buffer está lleno.
Código
// Producer-consumer pattern with bounded channel
// Patrón productor-consumidor con canal acotado
var items_ch: Map = Map.new()
fn produce() -> int {
var i: int = 0
while i < 5 {
let item: int = (i + 1) * 10
print("produced: " + int_to_string(item))
channel_send(items_ch, item)
i = i + 1
}
channel_send(items_ch, -1)
return 0
}
fn consume() -> int {
while true {
let item: int = channel_recv(items_ch)
if item < 0 { return 0 }
print("consumed: " + int_to_string(item))
}
return 0
}
fn main() -> int {
// Bounded channel — producer blocks if buffer is full
items_ch = channel_new(3)
let p: int = thread_spawn(produce)
let c: int = thread_spawn(consume)
thread_join(p)
thread_join(c)
channel_destroy(items_ch)
print("pipeline complete")
return 0
}
Salida
produced: 10 produced: 20 produced: 30 produced: 40 produced: 50 consumed: 10 consumed: 20 consumed: 30 consumed: 40 consumed: 50 pipeline complete
Explicación
El canal items_ch tiene una capacidad de 3, lo que significa que el productor puede enviar como máximo 3 elementos antes de bloquearse. Esto provee contrapresión natural -- si el consumidor es lento, el productor automáticamente se ralentiza para ajustarse.
El productor genera los valores 10, 20, 30, 40, 50 y los envía a través del canal, seguidos de un centinela -1 para señalar la finalización. El consumidor recorre en bucle channel_recv, procesando cada elemento hasta que ve el centinela.
El entrelazado exacto de los mensajes "produced" y "consumed" depende de la planificación del sistema, pero el orden dentro de cada flujo siempre se preserva. El buffer acotado evita que el productor sature al consumidor con datos.