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.
// 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 }
produced: 10 produced: 20 produced: 30 produced: 40 produced: 50 consumed: 10 consumed: 20 consumed: 30 consumed: 40 consumed: 50 pipeline complete
Cómo funciona
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.