2021-01-09 一时失言乱红尘 2023-01-04 10:28 89阅读 0赞 ### **sync.WaitGroup常规用法** ### **有点像countDownLatch的感觉** 通俗点说,两个角色,一种goroutine作为一个worker(他是个小弟),老老实实干活。另一种goroutine作为管理者督促小弟干活(它自己也是个worker)。 在有很多小弟干活时,管理者没事干歇着,但同时它又希望得到一个通知,知道小弟们什么时候干完活(所有小弟们一个不少全都干完活了)。这样管理者好对小弟的工作成果做验收。 如果没有sync.WaitGroup,怎么实现? 其实也不难,从程序开发角度看,就是维护一个小弟总数和一个通道。每个小弟干完活,就往通道发一个空消息, 管理者阻塞在通道的监听上。来一个消息就说明有一个小弟干完活了,记录下有多少个消息,消息个数和小弟总数一致。就说明全干活了,管理者关闭通道,验收小弟工作成果。 写成代码就是这样子 workers := 3 ch := make(chan struct{}) worker := func() { // 干活干活干活 ch <- struct{}{} // 通知管理者 } leader := func() { cnt := 0 for range ch { cnt++ if cnt == workers { break } } close(ch) // 检查工作成果 } go leader() for i := 0; i < workers; i++ { go worker() } 原理参见:[https://zhuanlan.zhihu.com/p/75441551][https_zhuanlan.zhihu.com_p_75441551] 改成sync.Waitgroup实现同样的功能就成这样子 wg := sync.WaitGroup{} workers := 3 wg.Add(workers) worker := func() { defer wg.Done() // 干活干活干活 } leader := func() { wg.Wait() // 检查工作成果 } go leader() for i := 0; i < workers; i++ { go worker() } Add,Done,Wait。三招完事。 语义很清晰。 知识点:sync.WaitGroup可以解决同步阻塞等待的问题。一个人等待一堆人干完活的问题得到优雅解决。 [https_zhuanlan.zhihu.com_p_75441551]: https://zhuanlan.zhihu.com/p/75441551
还没有评论,来说两句吧...