前言

如果你有一个工作能够分解成多个子工作进行解决,同时每个子工作没有先后执行程序的限度,等到全副子工作执行结束后,再进行下一步解决。这时每个子工作的执行能够并发解决,这种情景下适宜应用 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 - 两个在开发中需注意的小点