前言
如果你有一个工作能够分解成多个子工作进行解决,同时每个子工作没有先后执行程序的限度,等到全副子工作执行结束后,再进行下一步解决。这时每个子工作的执行能够并发解决,这种情景下适宜应用 sync.WaitGroup
。
尽管 sync.WaitGroup
应用起来比较简单,然而一不留神很有可能踩到坑里。
sync.WaitGroup 正确应用
比方,有一个工作须要执行 3 个子工作,那么能够这样写:
func main() { var wg sync.WaitGroup wg.Add(3) go handlerTask1(&wg) go handlerTask2(&wg) go handlerTask3(&wg) wg.Wait() fmt.Println("全副工作执行结束.")}func handlerTask1(wg *sync.WaitGroup) { defer wg.Done() fmt.Println("执行工作 1")}func handlerTask2(wg *sync.WaitGroup) { defer wg.Done() fmt.Println("执行工作 2")}func handlerTask3(wg *sync.WaitGroup) { defer wg.Done() fmt.Println("执行工作 3")}
执行输入:
执行工作 3执行工作 1执行工作 2全副工作执行结束.
sync.WaitGroup 闭坑指南
01
// 正确go handlerTask1(&wg)// 谬误go handlerTask1(wg)
执行子工作时,应用的 sync.WaitGroup
肯定要是 wg
的援用类型!
02
留神不要将 wg.Add()
放在 go handlerTask1(&wg)
中!
例如:
// 谬误var wg sync.WaitGroupgo handlerTask1(&wg)wg.Wait()...func handlerTask1(wg *sync.WaitGroup) { wg.Add(1) defer wg.Done() fmt.Println("执行工作 1")}
留神 wg.Add()
肯定要在 wg.Wait()
执行前执行!
03
留神 wg.Add()
和 wg.Done()
的计数器保持一致!其实 wg.Done()
就是执行的 wg.Add(-1)
。
小结
sync.WaitGroup
应用起来比较简单,肯定要留神不要踩到坑里。
其实 sync.WaitGroup
应用场景比拟局限,仅实用于期待全副子工作执行结束后,再进行下一步解决,如果需要是当第一个子工作执行失败时,告诉其余子工作进行运行,这时 sync.WaitGroup
是无奈满足的,须要应用到告诉机制(channel
)。
以上,心愿对你可能有所帮忙。
举荐浏览
- Go - 应用 sync.Map 解决 map 并发平安问题
- Go - 基于逃逸剖析来晋升程序性能
- Go - 应用 sync.Pool 来缩小 GC 压力
- Go - 应用 options 设计模式
- Go - 两个在开发中需注意的小点