【go从零单排】WaitGroup
🌈Don’t worry , just coding!
内耗与overthinking只会削弱你的精力,虚度你的光阴,每天迈出一小步,回头时发现已经走了很远。
📗概念
To wait for multiple goroutines to finish, we can use a wait group.
在 Go 中,WaitGroup 是一个用于等待一组 goroutine 完成的同步原语。它提供了一种简单的方法来阻塞主 goroutine,直到一组 goroutine 完成其工作。
WaitGroup 主要用于协调多个 goroutine 的执行,确保它们在程序继续执行之前都已完成。
💻代码
package main//导入 fmt 包用于输出,sync 包用于同步,time 包用于时间操作
import ("fmt""sync""time"
)// worker 函数接收一个 ID 参数,打印开始和完成的消息,模拟工作过程
func worker(id int) {fmt.Printf("Worker %d starting\n", id)time.Sleep(time.Second) // 模拟工作fmt.Printf("Worker %d done\n", id)
}func main() {//创建一个 WaitGroup 实例 wgvar wg sync.WaitGroupfor i := 1; i <= 5; i++ {wg.Add(1) // 增加等待的 goroutine 数量go func() {defer wg.Done() // 在函数结束时通知 WaitGroupworker(i) // 调用 worker 函数}()}wg.Wait() // 等待所有 worker 完成
}//输出
//Worker 5 starting
//Worker 2 starting
//Worker 3 starting
//Worker 1 starting
//Worker 4 starting
//Worker 4 done
//Worker 3 done
//Worker 2 done
//Worker 5 done
//Worker 1 done
🔍理解
- 使用 defer:在 goroutine 中使用 defer wg.Done() 是一种常见的做法,确保即使在出现错误或提前返回的情况下,也能正确减少计数。
- 计数器的管理:确保在每个 goroutine 启动之前调用 Add,并在每个 goroutine 完成时调用 Done。如果不匹配,可能会导致死锁或程序异常。
- 并发安全:WaitGroup 是并发安全的,可以在多个 goroutine 中安全地使用。
WaitGroup 主要有三个方法:
- Add(int):增加等待的 goroutine 数量。
- Done():减少等待的 goroutine 数量,通常在 goroutine 完成时调用。
- Wait():阻塞直到计数器为零,即所有 goroutine 都已完成。
💡 Tips小知识点
- 如果要将WaitGroup显示传递给函数,要用指针传递
- 在并发调用时,每次调用和完成的顺序可能会不同
💪无人扶我青云志,我自踏雪至山巅。