Let's say I have 2 goroutines, one running in another, each needs a waitgroup to prevent goroutine leak. Here is the code:
func A(wg *sync.WaitGroup) {
defer wg.Done()
// do something
}
func B(wg *sync.WaitGroup) {
defer wg.Done()
wg.Add(1) // <- this is for A()
go A(wg)
// do something
}
func main() {
wg := &sync.WaitGroup{}
wg.Add(1) // <- this is for B()
go B(wg)
// do something
wg.Wait()
}
It works well. But it is possible that the wg.Add(1)
line inside B()
is called after the wg.Wait()
in main()
started. The code is still working well in that case. But this seems to be a potential race condition to me.
Notice that this is not violating the WaitGroup rule: "calls with a positive delta that occur when the counter is zero must happen before a Wait". Here the Add()
inside B()
is happening when the counter is 1.
My question is: is it ok to call wg.Add()
in one goroutine when wg.Wait()
is blocking in another goroutine? If not, what's the best practice here? Apparently I can choose to not share one wairgroup for both A
and B
, instead to use 2 waitgroups for them respectively, but it will be pretty messy, especially when there are even more functions and we end up with a lot waitgroups to wait.