Goroutines y el WaitGroup en Go (Golang)
No hace mucho tiempo conocimos las gorutinas, una manera bastante sencilla que usa Go para trabajar programas concurrentes, siendo esta una de las características más atractivas del lenguaje consideré adecuado compartir unas par de cosas más sobre ellas con ustedes.
Goroutines y el WaitGroup en Go
Como he mencionado en varias ocasiones, la biblioteca estándar de Go es bastante amplia, nos provee de un gran número de herramientas muy útiles para diversos propósitos. El manejo de goroutines no podía ser la excepción. Vamos a partir de el último ejemplo de la publicación pasada.
package main
import (
"fmt"
"time"
)
func saludar(nombres []string) {
for _, nombre := range nombres {
fmt.Printf("Hola %s\n", nombre)
time.Sleep(1 * time.Second)
}
}
func despedir(nombres []string) {
for _, nombre := range nombres {
fmt.Printf("Adios %s\n", nombre)
time.Sleep(1 * time.Second)
}
}
func main() {
nombres := []string{"Orlando", "Daniela", "José", "Carlos", "Andrea", "David", "Carmen"}
go saludar(nombres)
go despedir(nombres)
var s string
fmt.Scan(&s)
}
}
No explicaré lo que este código hace, si tienes problemas para entenderlo te recomiendo leer primero esta publicación. Aclarado eso, hagamos algunas modificaciones.
package main
import (
"fmt"
"sync"
"time"
)
var wg sync.WaitGroup // Espera que una colección de goroutines se ejecute
func saludar(nombres []string) {
defer wg.Done() // Disminuye en uno la cantidad de goroutines a esperar
for _, nombre := range nombres {
fmt.Printf("Hola %s\n\r", nombre)
time.Sleep(1 * time.Second)
}
}
func despedir(nombres []string) {
defer wg.Done() // Disminuye en uno la cantidad de goroutines a esperar
for _, nombre := range nombres {
fmt.Printf("Adiós %s\n\r", nombre)
time.Sleep(1 * time.Second)
}
}
func main() {
wg.Add(2) // Añade la cantidad de goroutines a esperar
nombres := []string{"Orlando", "Daniela", "José",
"Carlos", "Andrea", "David", "Carmen"}
go saludar(nombres)
go despedir(nombres)
wg.Wait() // Espera hasta que se ejecuten las goroutines
fmt.Println("Fin del programa")
}
Gracias a las estructura WaitGroup
del paquete sync podemos definir una colección de goroutines cuya ejecución debe ser esperada antes de continuar con el proceso. Por medio del método Add
indicamos la cantidad de goroutines a esperar, el método Done
indica que una goroutine ha concluido y se resta del grupo de espera. No debería ser necesario explicar porque está siendo llamado en un defer
, pero igual lo haré, de esa forma nos aseguramos de que se ejecute al final de la función, no está directamente relacionado con las goroutines, y pudo omitirse, pero me parece más legible así.
Finalmente, el método Wait
obliga a esperar la ejecución del número de goroutines indicadas. Por tal motivo, la sentencia fmt.Println("Fin del programa")
se ejecutará después de que ambas goroutines concluyan su ejecución.
Publicaciones relacionadas
Gracias por leer, espero que este artículo te resultara de provecho. Si así fue, no dudes en dejar un comentario, compartirlo y votar. Te invito a comentar cualquier duda o sugerencia, te aseguro que las leo todas. Así que, por favor, ayúdame a mejorar y continuar compartiendo contenido de calidad. Si te gusta la programación y/o la informática en general, te invito a formar parte de la comunidad Develop Spanish dónde compartimos contenido de esa naturaleza y totalmente en español. Hasta la próxima.
Hello! Your post has been resteemed and upvoted by @ilovecoding because we love coding! Keep up good work! Consider upvoting this comment to support the @ilovecoding and increase your future rewards! ^_^ Steem On!
Reply !stop to disable the comment. Thanks!