In Golang, you can use WaitGroup
to await a collection of goroutines to finish. Let's take a look at the below example
package main
import (
"fmt"
//"time"
)
func f(s string) {
fmt.Println(s)
}
func main() {
go f("i'm async!")
go func(s string) {
fmt.Println(s)
}("i'm async too!")
//time.Sleep(time.Second)
fmt.Println("done!")
}
The number of output strings will vary as the program may have exited before all goroutines completion.
You can use time.Sleep
by assuming a duration, however sync.WaitGroup
is a better way in practice to handle the case. The following gives you an implementation example with WaitGroup
WaitGroup
is a struct
defined in the sync
package. It maintains a counter to wait for a collection of goroutines to finish. In the above program
waitGroup.Add(1)
adds a delta to theWaitGroup
counterwaitGroup.Done()
decreases theWaitGroup
counter by onewaitGroup.Wait()
blocks until theWaitGroup
counter is zero
Now, the quantity of output strings is always consistent (the ordering may be different for each invocation)
i'm async too!
i'm async!
done!
WaitGroup.Wait() timeout
WaitGroup.Wait()
doesn't have a timeout option. The following example gives you an implementation example by using channel
and select
Output
i'm async!
Wait timeout!
A select
blocks until one of its cases is ready to run
In the above waitTimeout
method definition, the second select
case is ready before the first case as the second goroutine execution time (time.Sleep(2*time.Second)
) is greater than the wait timeout parameter (waitGroup.waitTimeout(time.Second)
). You can try to comment out the line time.Sleep(2*time.Second)
to see the different outputs