Cómo Go, Kotlin y Erlang resuelven la concurrencia: el papel del GC y del planificador

Fuentes: A Quick Rundown on Concurrency and GC

Este documento técnico explica cómo tres lenguajes —Go, Kotlin y Erlang/Elixir sobre BEAM— afrontan el mismo reto: ejecutar muchas tareas lógicas sobre pocos hilos del sistema operativo. La clave está en quién controla el cambio entre tareas y qué necesita saber ese controlador para hacerlo de forma segura. Esa decisión determina si el modelo es cooperativo o preemptivo, si las pausas del recolector de basura afectan a un hilo o a todo el proceso, y si un error queda contenido o se propaga.

El texto parte de una idea común: un núcleo de CPU ejecuta un único flujo de instrucciones a la vez y los hilos del sistema operativo son demasiado costosos para asignar uno por tarea lógica. Por eso los tres entornos construyen planificadores M:N, que multiplexan M tareas lógicas sobre N hilos. A partir de ahí, cada lenguaje toma un camino distinto.

En el caso de Go, se describe la herencia del modelo CSP de Tony Hoare (1978): procesos secuenciales que se comunican solo por canales, sin estado mutable compartido. Se detalla el diseño del planificador con sus componentes G, M y P, la evolución desde el modelo cooperativo de Go ≤1.10 hasta la preempción no cooperativa basada en señales de Go 1.14, y la relación entre la preempción y las pausas stop-the-world del GC. Cada sección incluye preguntas de comprobación para verificar la comprensión antes de avanzar.