共计 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 – 两个在开发中需注意的小点
正文完