sync.WaitGroup and nested loops

Issue

I’d like to add concurrency for iterating nested loops but having a trouble. What’s wrong with this example usage of sync.WaitGroup?

originCities := [3]string{"LED", "MOW", "PRS"}
destinationCities := [2]string{"UKT", "AAC"}

wg := &sync.WaitGroup{}
wg.Add(len(originCities) * len(destinationCities))

for _, originIata := range originCities {
    for _, destinationIata := range destinationCities {
        go func () {
            fmt.Println(originIata)
            fmt.Println(destinationIata)
            wg.Done()
        }()
    }
}
wg.Wait()

I’m getting

PRS AAC PRS AAC PRS AAC PRS AAC PRS AAC PRS AAC

So as you may see it’s skipping first elements of both array and iterating only the last ones. Any ideas how to fix this behavior?

Solution

It’s a closure problem. You need to pass values to your goroutine inside the loop, like this:

for _, originIata := range originCities {
    for _, destinationIata := range destinationCities {
        go func (originIata, destinationIata string) {
            fmt.Println(originIata)
            fmt.Println(destinationIata)
            wg.Done()
        }(originIata, destinationIata)
    }
}

Answered By – Clément

Answer Checked By – Katrina (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.