Concurrencia en Go: gorutinas, canales y async/await (comparación)

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

¿Por qué Go superó a todos en concurrencia?

\n\n

Imagínese un chef que prepara diez platos simultáneamente. No corre de una estufa a otra a toda velocidad — simplemente cambia eficientemente entre tareas: mientras se cocina la carne, corta la ensalada; mientras hierve el agua, emplata. En el mundo de la programación, esto se llama concurrencia — la habilidad de gestionar múltiples tareas sin esperar a que cada una termine.

\n\n

El lenguaje Go (Golang) nació precisamente para resolver problemas de concurrencia. Sus creadores de Google se cansaron de las complejidades del multihilo en C++ y Java. Inventaron las gorutinas — hilos ligeros que se inician con una sola línea de código. En este artículo, analizaremos cómo funciona la concurrencia en Go, la compararemos con los hilos del SO y el paradigma async/await de Python y, lo más importante, mostraremos ejemplos de código reales que podrá aplicar hoy mismo.

\n\n

Gorutinas vs Hilos del SO: batalla de la caballería ligera

\n\n

Cuando un desarrollador oye «multihilo», normalmente piensa en hilos del sistema operativo. Pero en Go es diferente. Analicemos las diferencias clave.

\n\n

¿Qué es un hilo del SO (Thread)?

\n

Un hilo es un objeto pesado gestionado por el núcleo del SO. Cada hilo tiene su propia pila (normalmente 1-8 MB), requiere llamadas al sistema para crearse y cambiar de contexto. Crear 10 000 hilos significa agotar la memoria y la CPU. Go tiene una filosofía diferente.

\n\n

Gorutina (Goroutine) — el hilo ligero de Go

\n

Una gorutina es una función que se ejecuta de forma concurrente. Se inicia con la palabra clave go. Sus principales características:

\n
    \n
  • Tamaño de pila: comienza con 2-4 KB y crece/encoge dinámicamente.
  • \n
  • Creación: miles de gorutinas se crean en milisegundos.
  • \n
  • Planificador: el runtime de Go distribuye las gorutinas entre los hilos del SO (normalmente tantos como núcleos de CPU).
  • \n
  • Sintaxis: simplemente añada go antes de la llamada a la función.
  • \n
\n\n
package main\n\nimport (\n    "fmt"\n    "time"\n)\n\nfunc sayHello(name string) {\n    for i := 0; i < 3; i++ {\n        fmt.Println("Hola,", name)\n        time.Sleep(100 * time.Millisecond)\n    }\n}\n\nfunc main() {\n    // Iniciamos dos gorutinas\n    go sayHello("Go")\n    go sayHello("Goroutine")\n\n    // Damos tiempo a las gorutinas para ejecutarse\n    time.Sleep(1 * time.Second)\n    fmt.Println("Función principal finalizada")\n}
\n\n

Resultado: los mensajes de las dos gorutinas se mezclarán. Go cambia automáticamente entre ellas sin bloquearse mutuamente. Intente ejecutar este código — verá cómo «Hola, Go» y «Hola, Goroutine» se muestran alternativamente.

\n\n

Canales: la principal herramienta de sincronización

\n\n

Las gorutinas son geniales, pero ¿cómo se comunican? En Go no hay memoria compartida por defecto. En su lugar, se usa el principio: «No se comunique compartiendo memoria; comparta memoria comunicándose». Para ello sirven los canales (channels).

\n\n

Un canal es un «conducto» tipificado a través del cual las gorutinas envían y reciben datos. Es seguro, simple y elegante.

\n\n

Ejemplo: procesamiento paralelo de números

\n
package main\n\nimport "fmt"\n\nfunc squareWorker(numbers <-chan int, results chan<- int) {\n    for n := range numbers {\n        results <- n * n\n    }\n    close(results)\n}\n\nfunc main() {\n    numbers := make(chan int, 5)\n    results := make(chan int, 5)\n\n    // Iniciamos el trabajador\n    go squareWorker(numbers, results)\n\n    // Enviamos datos\n    numbers <- 2\n    numbers <- 4\n    numbers <- 6\n    close(numbers)\n\n    // Leemos los resultados\n    for res := range results {\n        fmt.Println("Cuadrado:", res)\n    }\n}
\n\n

En este ejemplo, usamos canales con búfer (el segundo argumento es el tamaño del búfer). La gorutina trabajadora lee del canal numbers, eleva al c

Blogs

Book Recommendations