【Go语言入门教程】WaitGroup 实现并发等待
2023-09-11 14:19:28 时间
![](https://img-blog.csdnimg.cn/833c38c9741d41978211c5cd179dad68.png)
WaitGroup 实现并发等待
- WaitGroup 类实现的功能是:等待一系列协程并发地执行完毕。如果不等待所有协程执行完毕,可能会导致一些线程安全问题。sync.WaitGroup 包含 3 个方法:
方法 | 作用 |
---|---|
Add(delta int) | 主协程调用该方法,设置 delta 为需要等待的协程数量 |
Done() | 每个子协程运行起来,当每个子协程执行结束后,调用 Done() 表示子协程运行结束, delta – |
Wait() | 当所有协程执行完毕后,代码块可使用 Wait() ,当 delta ==0时,才执行后续代码 |
例子:优化 hello.go
程序
//原来的代码
package main
import (
"fmt"
"time"
)
func hello(i int) {
fmt.Printf("hello goroutine: %v\n", i)
}
func main() {
for i := 0; i < 5; i++ {
go func(j int) {
hello(j)
}(i)
}
time.Sleep(time.Second) //等待上面的协程执行完毕
}
输出:
hello goroutine: 1
hello goroutine: 2
hello goroutine: 0
hello goroutine: 3
hello goroutine: 4
在旧的代码中,第 19 行:由于不清楚上面 5 个协程什么时候执行完毕,因此只能人为粗略地估计协程 1 秒后执行完毕。因此,只能通过暴力调用 time.Sleep()
来等待 1 秒。调用 WaitGroup 后,就能自动判断所有协程执行完毕,立马开始后续代码的执行,提高程序运行效率。
package main
import (
"fmt"
"sync"
)
func hello(i int) {
fmt.Printf("hello goroutine: %v\n", i)
}
func main() {
wg := sync.WaitGroup{} //WaitGroup类实例化
//1.调用Add(),声明协程的数量delta=5
wg.Add(5)
//协程执行
for i := 0; i < 5; i++ {
go func(j int) {
//2.每个协程执行完后,调用Done(),delta--
defer wg.Done()
hello(j)
}(i)
}
//3.调用Wait(),等待全部协程执行完毕(即delta==0),才执行后续代码
wg.Wait()
fmt.Println("所有协程执行完毕,可执行下一项操作...")
}
输出:
hello goroutine: 4
hello goroutine: 1
hello goroutine: 0
hello goroutine: 3
hello goroutine: 2
所有协程执行完毕,可执行下一项操作...
优化后的代码无需等待 1 秒,可以等所有协程执行完毕后,自动无缝切换后续代码的执行。
相关文章
- Go语言并发机制
- 《Go语言实战》摘录:6.3 并发 - 竞争状态
- 《Go语言实战》摘录:6.4 并发 - 锁住共享资源
- 《Go语言实战》摘录:7.1 并发模式 - runner
- 【Go命令教程】7. go run
- 【Go语言】【6】GO语言的数组
- 【Go语言】【5】GO语言变量
- 【Go语言】【3】GO语言常量
- 【Go语言】【15】GO语言的面向对象
- 【Go语言】【11】GO语言的包和函数
- 【Go语言】【9】GO语言的循环语句
- [Go] golang 替换组件包 更新 go.mod, go.sum 的方式
- 【Go环境】配置go环境变量、go mod命令大全
- go并发之WaitGroup
- Go语言并发机制初探
- GO语言教程(一)Linux( Centos)下Go的安装, 以及HelloWorld
- Go 并发、并行和协程
- Mac上搭建Go语言环境及第一个hello.go程序