Sincronización de Rutinas en Go con Wait Group

Clase 23 de 30Curso de Go Intermedio: Programación Orientada a Objetos y Concurrencia

Resumen

¿Cómo sincronizar rutinas con wait groups en Go?

En el mundo de la programación concurrente, Go nos ofrece herramientas optimizadas para manejar múltiples tareas simultáneas sin complicaciones. Una de estas herramientas esenciales son los wait groups, que nos permiten sincronizar la ejecución de múltiples rutinas. En esta guía, te explicamos cómo funcionan y cómo puedes utilizarlos en tus proyectos.

¿Qué es un wait group?

Un wait group es un mecanismo en Go que actúa como un contador basado en el número de gorutinas que deben completar su trabajo antes de que el programa principal continúe. Es una alternativa eficaz a los canales cuando solo necesitas asegurarte de que todas tus tareas concurrentes han finalizado.

¿Cómo se implementa un wait group en Go?

La implementación de un wait group en Go es bastante sencilla y se logra mediante los siguientes pasos:

  1. Crear un wait group: Primero, debes importar el paquete sync que proporciona la estructura de wait group. Luego, puedes crear una variable de tipo sync.WaitGroup.

    var wg sync.WaitGroup
    
  2. Agregar al contador: Cada vez que inicias una nueva gorutina, incrementas el contador del wait group con el método Add.

    wg.Add(1)
    
  3. Disminuir el contador: Dentro de cada gorutina, asegúrate de decrementar el contador del wait group cuando la gorutina finalice utilizando Done.

    defer wg.Done()
    
  4. Esperar a que todas las gorutinas terminen: Usa wg.Wait() en tu función principal para bloquearla hasta que todas las gorutinas han terminado su ejecución; es decir, hasta que el contador vuelve a cero.

    wg.Wait()
    

Ejemplo práctico de uso de wait groups

Para ilustrar cómo funciona un wait group, vamos a realizar un ejemplo práctico en el que lanzamos múltiples tareas que simulan un proceso prolongado:

package main

import (
    "fmt"
    "sync"
    "time"
)

func doSomething(id int, wg *sync.WaitGroup) {
    defer wg.Done()
    fmt.Printf("Goroutine %d inició\n", id)
    time.Sleep(2 * time.Second)
    fmt.Printf("Goroutine %d terminó\n", id)
}

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 10; i++ {
        wg.Add(1)
        go doSomething(i, &wg)
    }

    wg.Wait()
    fmt.Println("Todas las gorutinas han terminado.")
}

Beneficios del uso de wait groups

  • Simplicidad: Implementar wait groups es fácil y directo, facilitando la sincronización de tareas concurrentes.
  • Control: Permite un control efectivo y seguro sobre la finalización de las gorutinas.
  • Readabilidad: Mejora la legibilidad del código, haciendo evidente para otros programadores cuándo y cómo se sincronizan las tareas.

Con estas herramientas, podrás gestionar tus programas concurrentes con mayor eficiencia. ¡No dudes en implementar wait groups en tus próximos proyectos para ver por ti mismo los beneficios que ofrecen! Y recuerda, en la programación concurrente, la práctica hace al maestro. Sigue explorando y experimentando con nuevas formas de optimizar tus códigos.