关于后端:Go-使用-syncWaitGroup-来实现并发操作

39次阅读

共计 1196 个字符,预计需要花费 3 分钟才能阅读完成。

前言

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

go 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 – 两个在开发中需注意的小点

正文完
 0