[Go] Go routines with WaitGroup and async call

So, let's say we have a function to fetch crypto currencies price:

package main

import (
	"fmt"
	"sync"

	"project/api"
)

func main() {
    go getCurrencyData("BTC")
    go getCurrencyData("BCH")
    go getCurrencyData("ETH")
}

func getCurrencyData(currency string) {
	rate, err := api.GetRate(currency)

	if err == nil {
		fmt.Printf("The rate for %v is %.2f \n", rate.Currency, rate.Price)
	}
}

We know what will happen for this code, after main function ends, all the program ends automaticlly, we might see nothing from the output.

 

WaitGroup

WaitGroup can helps, let change code a little bit:

func main() {
	currencies := []string {"BTC", "ETH", "BCH"}
	var wg sync.WaitGroup

	for _, currency := range currencies {
	    wg.Add(1)
	    go getCurrencyData(currency)
        wg.Done()
	}

	wg.Wait()
}

Well, current code won't work, but it is important to understand what WaitGroup doing for us, so basiclly it add 1 to a internal count of waitgroup by calling Add(1), and also subtract 1 by calling Done()Wait()is used to wait the internal counter to be zero.

But why it doesn't work,  it is because after go getCUrrencyData(currency)wg.Done()get called immedicatly, we are not waiting go getCurrencyData(currency) to finish at all

go getCurrencyData(cy) // do work in another thread
wg.Done() // continue in main thread

 

Using Async call

Now, let modify the code to make it work

func main() {
	currencies := []string {"BTC", "ETH", "BCH"}
	var wg sync.WaitGroup

	for _, currency := range currencies {
		wg.Add(1)
		go func (cy string) {
			getCurrencyData(cy)
			wg.Done()
		}(currency)
	}

	wg.Wait()
}

We wrap getCurrencyDataand wg.Done()in a go func() {}().

Since getCurrencyDataand wg.Done()are now working in sync, so wg.Done()will actually work.

posted @ 2024-02-06 22:03  Zhentiw  阅读(3)  评论(0编辑  收藏  举报