Translate

martes, 20 de enero de 2026

Concurrencia en Crystal: Fibers y Channels al Estilo Go


El lenguaje Crystal combina la sintaxis elegante de Ruby con un modelo de concurrencia ligero y eficiente, inspirado en Go.

En lugar de hilos del sistema operativo, Crystal usa fibers, que permiten ejecutar múltiples tareas de forma concurrente dentro del mismo proceso.

Una fiber es una unidad ligera de ejecución gestionada por el runtime de Crystal (no por el sistema operativo).

Varias fibers pueden ejecutarse “en paralelo” sobre un solo hilo de sistema, haciendo que la concurrencia sea cooperativa y eficiente.


Se crean usando la palabra clave spawn:


spawn do

  puts "Hola desde una fiber!"

end


puts "Hola desde el hilo principal!"

sleep 0.1


Salida posible:

Hola desde el hilo principal!

Hola desde una fiber!


El sleep al final evita que el programa termine antes de que la fiber se ejecute (las fibers corren de forma asíncrona).

Las fibers se comunican a través de channels, una abstracción segura para enviar y recibir mensajes sin necesidad de locks.


channel = Channel(String).new

spawn do

  channel.send("Mensaje desde otra fiber")

end


puts channel.receive


Salida:

Mensaje desde otra fiber


Los Channel son tipados (Channel(Int32), Channel(String), etc.), y pueden usarse para coordinar tareas concurrentes.


Veamos un ejemplo más realista con varias fibers:


channel = Channel(Int32).new


# Productor

spawn do

  5.times do |i|

    puts "Produciendo #{i}"

    channel.send(i)

    sleep 0.2

  end

  channel.close

end


# Consumidor

spawn do

  for value in channel

    puts "Consumiendo #{value}"

  end

end


sleep 2


Salida:

Produciendo 0

Consumiendo 0

Produciendo 1

Consumiendo 1

Produciendo 2

Consumiendo 2

Produciendo 3

Consumiendo 3

Produciendo 4

Consumiendo 4


Crystal no crea múltiples hilos del sistema por cada fiber.

Las fibers son gestionadas por el scheduler del runtime.

El modelo es asíncrono cooperativo: las fibers ceden el control cuando hacen operaciones de I/O o esperan datos.

Este enfoque reduce el costo de cambio de contexto y permite miles de fibers concurrentes sin overhead.

Crystal adopta el modelo CSP (Communicating Sequential Processes) de Go, pero mantiene la simplicidad y legibilidad de Ruby.

Es importante notar que Crystal 1.x usa un solo hilo del sistema (no hay paralelismo real entre núcleos).

Sin embargo, el equipo de Crystal está trabajando en soporte multithreaded para futuras versiones.


Esto significa que las fibers son ideales para:

  • I/O concurrente (HTTP, base de datos, archivos).
  • Operaciones asíncronas livianas.
  • Pero no para tareas intensivas en CPU.


La concurrencia en Crystal es una de sus características más elegantes:

  • Usa fibers para tareas concurrentes sin complicaciones.
  • Permite comunicación segura con channels.
  • Ofrece un modelo simple, escalable y eficiente.


Si disfrutás del enfoque de Go o Elixir, pero querés la sintaxis de Ruby y velocidad de C, Crystal es una alternativa brillante para explorar.