Go programs end when the main
function ends, therefore it is common practice to wait for all goroutines to finish. A common solution for this is to use a sync.WaitGroup object.
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup // 1
func routine(i int) {
defer wg.Done() // 3
fmt.Printf("routine %v finished\n", i)
}
func main() {
wg.Add(10) // 2
for i := 0; i < 10; i++ {
go routine(i) // *
}
wg.Wait() // 4
fmt.Println("main finished")
}
Run the example in the playground
WaitGroup usage in order of execution:
* Parameters are evaluated before starting a new goroutine. Thus it is necessary to define their values explicitly before wg.Add(10)
so that possibly-panicking code will not increase the counter. Adding 10 items to the WaitGroup, so it will wait for 10 items before wg.Wait
returns the control back to main()
goroutine. Here, the value of i is defined in the for loop.