Handle goroutines with sync.Waitgroup

Simple example on how to handle concurency with sync.WaitGroup.
Simple example on how to handle concurency with sync.WaitGroup.
If you are gonna do alot of requests at the same time, it could be a good idea to put them in goroutines to be more efficient. I want to show you how you can handle this in a easy way using sync.WaitGroup.
First we create a WaitGroup
variable which we will use to control our goroutines, and a struct that will contain the response from the dog api we are gonna use in this example.
var wg sync.WaitGroup
var img struct {
Status string
Message string
}
Then we create a easy get
request function to test our code:
func randomDogImage(i *img, wg *sync.WaitGroup) {
defer wg.Done() // notice this
resp, err := http.Get("https://dog.ceo/api/breeds/image/random")
if err != nil {
fmt.Errorf("Failed http get request: %v", err)
return
}
defer resp.Body.Close()
err = json.NewDecoder(resp.Body).Decode(i)
if err != nil {
fmt.Errorf("Could not decode json: %v", err)
return
}
}
Notice the defer wg.Done()
.
This will tell the WaitGroup
that this goroutine is “done”. Without calling this function the program will end up in a deadlock, since the WaitGroup
will be forever waiting for the wg.Done()
being called.
Then we can continue like this:
var i1, i2, i3, i4 img
wg.Add(1)
go randomDogImage(&i1, &wg)
wg.Add(1)
go randomDogImage(&i2, &wg)
wg.Add(1)
go randomDogImage(&i3, &wg)
wg.Add(1)
go randomDogImage(&i4, &wg)
wg.Wait()
// This will print when all requests are done
fmt.Println(i1.Message)
fmt.Println(i2.Message)
fmt.Println(i3.Message)
fmt.Println(i4.Message)
wg.Wait()
will wait until all your goroutines are done before continuing.
Thanks for reading.