能sync.WaitGroup后可重复使用Wait()被称为?
sync.WaitGroup
Wait()
func worker(who string, in <-chan int, wg *sync.WaitGroup) { for i := range in { fmt.Println(who, i) wg.Done() } } func main() { var wg sync.WaitGroup AIn := make(chan int, 1) BIn := make(chan int, 1) go worker("a:", AIn, &wg) go worker("b:", BIn, &wg) for i := 0; i < 4; i++ { wg.Add(2) AIn <- i BIn <- i wg.Wait() fmt.Println("main:", i) } }
这play.golang.org/p/QLsvA-b4Ae按预期运行,但它保证是安全的吗?文档没有这么说,但也许我只是偏执。
是的,这很安全。实际上,它比这更安全。您可以同时Wait从多个goroutine中进行选择,并可以根据您的用例进行适当的互换Add和Done调用。只要Add发生在之前Wait,您就应该是安全的。
Wait
Add
Done
出于好奇,现在WaitGroup使用互斥锁,两个int32s计数器和一个信号量来实现:
WaitGroup
type WaitGroup struct { m Mutex counter int32 waiters int32 sema *uint32 }
这也是一个有趣的测试:
var wg1, wg2 sync.WaitGroup wg1.Add(1) wg1.Done() wg1.Wait() fmt.Println(wg1 == wg2) // Prints true
最后,如果您发现这种用法有任何问题,请报告,因为这将是一个错误。