WaitGroups Go
En Go, es común ejecutar varias goroutines en paralelo para aprovechar la concurrencia del lenguaje. Sin embargo, coordinar la finalización de estas goroutines puede ser un desafío. Aquí es donde los WaitGroups
resultan esenciales.
En esta sección aprenderé cómo esperar de manera eficiente a que un conjunto de goroutines terminen su ejecución antes de que el programa continúe mediante los WG
¿Qué es un WaitGroup?
Un WaitGroup
es un contador de goroutines que se utilizan para sincronizar la ejecución en Go. Con un WaitGroup
, puedes decirle al programa que espere a que un conjunto de goroutines termine su trabajo antes de continuar con la siguiente tarea. Este mecanismo es crucial para evitar que el programa termine antes de que las goroutines hayan completado su trabajo.
Uso Básico de WaitGroups
La funcionalidad de WaitGroup
se maneja principalmente a través de tres métodos:
Add(delta int)
: Incrementa el contador delWaitGroup
por el valor dedelta
.Done()
: Decrementa el contador delWaitGroup
en uno. Este método es típicamente llamado por las goroutines cuando terminan su trabajo.Wait()
: Bloquea la ejecución hasta que el contador delWaitGroup
llegue a cero.
Ejemplo Básico: Sincronización de Goroutines
Explicación del Código
Declaración del
WaitGroup
: Se declara unWaitGroup
(var wg sync.WaitGroup
) para controlar la sincronización de las goroutines.Incremento del Contador con
Add
: Dentro del bucle,wg.Add(1)
incrementa el contador delWaitGroup
cada vez que se lanza una nueva goroutine.Decremento del Contador con
Done
: Dentro de cada goroutine,defer wg.Done()
asegura que el contador se decremente cuando la goroutine termine.Espera a la Finalización con
Wait
: Finalmente,wg.Wait()
bloquea la ejecución hasta que todas las goroutines hayan llamado aDone()
y el contador llegue a cero.Con &wg paso una referencia al objeto Wg: ya que al usar
&wg
, estoy pasando la dirección de memoria del objetowg
, lo que permite que las goroutines accedan y modifiquen el mismoWaitGroup
en lugar de trabajar con una copia.
Salida esperada:
Asegurando el Uso Correcto de WaitGroups
Uso de Add
antes de Lanzar la Goroutine
Add
antes de Lanzar la GoroutineEs importante siempre llamar a wg.Add(1)
antes de lanzar la goroutine. Si Add
se llama después, existe la posibilidad de que Wait
termine antes de que la goroutine se registre en el WaitGroup
, lo que puede llevar a un comportamiento inesperado.
Ejemplo Incorrecto:
Este código puede resultar en un comportamiento inesperado porque wg.Wait()
podría ejecutarse antes de que todas las goroutines llamen a Add(1)
.
Evitar los Panics por Llamadas Incorrectas
Es crucial que el número de llamadas a wg.Done()
coincida con el número de llamadas a wg.Add()
. De lo contrario, puedes encontrarte con un panic
si el contador de WaitGroup
se vuelve negativo.
Ejemplo de Error Común:
En este ejemplo, el programa se bloqueará en wg.Wait()
porque no se llama a wg.Done()
en la goroutine, lo que impide que el contador llegue a cero.
Ejemplo Completo: Sincronización de Múltiples Tareas Concurrentes
Para mostrar el poder de los WaitGroups
, consideremos un ejemplo donde diferentes goroutines realizan diferentes tareas de duración variable.
Explicación del Código
Función
tareaRapida
: Simula una tarea que toma 1 segundo en completarse.Función
tareaLenta
: Simula una tarea que toma 3 segundos en completarse.Sincronización: Ambas tareas se ejecutan en paralelo, y
wg.Wait()
asegura que el programa no termine hasta que ambas goroutines completen su trabajo.
Salida esperada:
Conclusión
Los WaitGroups
son una herramienta esencial en Go para manejar la sincronización de goroutines de manera eficiente. Aseguran que un conjunto de tareas concurrentes termine antes de proceder con la siguiente parte del programa, lo que es crucial para evitar problemas comunes en programación concurrente como condiciones de carrera o bloqueos inesperados.
Usando Add
, Done
y Wait
correctamente, puedes escribir código concurrente robusto y fácil de mantener.
Last updated