使用Go Goroutine并行计算数组最大值遇死锁,求技术指导
问题分析与修复
死锁原因
原代码的核心问题在于主循环中每次迭代两次读取channel:
- 10个goroutine总共向channel发送10个值
- 主循环执行10次,每次
if max < <-ch读取一次,max = <-ch又读取一次,总共需要读取20个值 - 当10个值被读完后,主goroutine会阻塞在channel读取操作上,没有其他goroutine发送数据,最终触发死锁
基础修复(解决死锁)
先修正读取逻辑,每次迭代只读取一次channel值:
package main import ( "fmt" "math" ) func main() { arr := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} max := math.MinInt32 ch := make(chan int) for i := 0; i < len(arr); i++ { go func(i int) { ch <- arr[i] }(i) } // 修正:每次迭代只读取一次channel值 for i := 0; i < len(arr); i++ { val := <-ch if max < val { max = val } } fmt.Println(max) }
结合Wait Group的优化方案(符合需求)
按照你要求的使用WaitGroup管理goroutine,同时更优雅地处理channel关闭,避免依赖数组长度控制循环次数:
package main import ( "fmt" "math" "sync" ) func main() { arr := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} max := math.MinInt32 ch := make(chan int) var wg sync.WaitGroup wg.Add(len(arr)) for i := 0; i < len(arr); i++ { go func(i int) { defer wg.Done() ch <- arr[i] }(i) } // 单独启动goroutine,等待所有任务完成后关闭channel go func() { wg.Wait() close(ch) }() // 遍历channel直到关闭,计算最大值 for val := range ch { if val > max { max = val } } fmt.Println(max) }
关键说明
WaitGroup用于等待所有goroutine完成数据发送任务- 单独goroutine在
WaitGroup等待完成后关闭channel,主goroutine的range循环会在channel关闭后自动退出 - 避免硬编码循环次数,代码更健壮,适配数组长度变化的场景
内容的提问来源于stack exchange,提问作者Subhrajit Makur
相关产品推荐
相关产品推荐

