如何使用sync.WaitGroup执行所有goroutine并替代time.Sleep?
解决Go语言中等待所有goroutine处理完成再退出的问题
原代码存在的问题
- 发送数据的goroutine未关闭通道,接收方无法知晓数据是否发送完毕
quit通道发送时机过早,导致处理goroutine提前退出,未完成所有数值的平方计算- 遍历切片时错误使用索引而非切片元素,实际计算的是0-9的平方而非目标的1-10的平方
time.Sleep属于被动等待,无法精准匹配goroutine的处理时长
修正后的代码
package main import ( "fmt" "sync" ) func doSquare(num int) int { return num * num } var wg sync.WaitGroup func main() { st := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} ch := make(chan int) // 发送数据的goroutine:发送所有数值后关闭通道 go func() { for _, num := range st { ch <- num } close(ch) // 关闭通道告知接收方无更多数据 }() wg.Add(1) // 处理数据的goroutine:遍历通道直到关闭,完成后标记WaitGroup go func() { defer wg.Done() // 确保goroutine退出时执行Done for x := range ch { fmt.Println(doSquare(x)) } }() // 等待所有处理goroutine完成 wg.Wait() }
关键改动说明
- 关闭通道:发送完所有数值后关闭
ch,接收方通过range ch可以自动感知通道关闭,从而退出循环 - 修正切片遍历:使用
for _, num := range st获取切片元素而非索引,确保计算的是目标数值的平方 - 正确使用WaitGroup:在启动处理goroutine前调用
wg.Add(1),处理goroutine内用defer wg.Done()保证无论正常退出还是异常退出都会标记完成,最后通过wg.Wait()阻塞主goroutine,直到所有工作goroutine完成 - 移除不必要的quit通道和time.Sleep:通过通道关闭+WaitGroup的组合实现精准等待,避免被动休眠
内容的提问来源于stack exchange,提问作者Pygirl
相关产品推荐
相关产品推荐

