Sobes.tech
Junior

¿En qué se diferencian las goroutines de los hilos (threads)?

sobes.tech AI

Respuesta de la IA

Las goroutines difieren de los hilos (threads) en los siguientes aspectos clave:

  • Gestión: Las goroutines son gestionadas por el entorno de ejecución de Go, mientras que los hilos son gestionados por el sistema operativo. Esto hace que cambiar entre goroutines sea mucho más ligero y rápido, ya que no requiere cambiar el contexto del núcleo.
  • Costos: Crear y gestionar goroutines requiere mucho menos recursos (memoria y tiempo) en comparación con los hilos. Una goroutine comienza con una pila muy pequeña (unos pocos kilobytes), que puede crecer o reducirse dinámicamente según sea necesario, mientras que los hilos tienen una pila fija, a menudo mucho mayor.
  • Escalabilidad: Gracias a sus bajos costos, es fácil crear cientos de miles o incluso millones de goroutines en una sola aplicación, mientras que crear la misma cantidad de hilos agotará rápidamente los recursos del sistema.
  • Planificación: El planificador de Go multiplexa muchas goroutines en un menor número de hilos del sistema operativo. Esto implementa la multitarea cooperativa entre goroutines en un solo hilo del sistema operativo (aunque con elementos de preempción), mientras que los hilos del sistema operativo son gestionados por el planificador del sistema operativo, que utiliza multitarea preemptiva.
Aspecto Goroutines Hilos (Threads)
Gestión Entorno de ejecución de Go Sistema operativo
Costos Bajos (memoria, tiempo) Altos (memoria, tiempo)
Escalabilidad Muy alta Limitada por recursos del sistema
Planificación Planificador de Go (cooperativo) Planificador del SO (preemptivo)
Pila Dinámica, pequeña Fija, a menudo grande

Ejemplo de creación de una goroutine:

package main

import (
	"fmt"
	"time"
)

func tarea(id int) {
	fmt.Printf("Goroutine %d comenzó\n", id)
	time.Sleep(time.Second)
	fmt.Printf("Goroutine %d terminó\n", id)
}

func main() {
	go tarea(1) // Creación de una goroutine
	go tarea(2) // Creación de otra goroutine

	time.Sleep(2 * time.Second) // Esperamos a que las goroutines terminen
	fmt.Println("Goroutine principal finalizada")
}