Go并发求和代码为何输出0?预期结果应为20
Go并发求和结果为0的问题分析与修复
问题原因分析
你的代码存在两个核心问题,直接导致输出结果为0:
1. WaitGroup计数添加时机错误
process_all是在goroutine中执行的,而main函数里的wg.Wait()会在这个goroutine执行wg.Add(len(inputs)+1)之前就运行。此时WaitGroup的计数为0,wg.Wait()直接返回,紧接着执行close(c)。
当sum_results函数尝试遍历通道c时,通道已经被关闭且没有任何数据,循环直接结束,sum保持初始值0,最终将0发送到result通道,导致输出0。
2. 切片遍历错误获取索引而非元素
process_all函数中的for input := range inputs遍历的是切片的索引值(0、1、2、3、4),而非切片里的元素(1、2、3、4、5)。即使前面的WaitGroup问题修复,逻辑上也是错误的,只是巧合数值结果和预期一致。
另外,process_all里的wg.Add(len(inputs)+1)属于冗余操作:+1是为了自身的defer wg.Done(),但process_all本身不需要被WaitGroup等待,我们只需要等待所有process_input的goroutine完成即可。
修复后的代码
package main import ( "fmt" "sync" ) func main() { input := []int{1, 2, 3, 4, 5} c := make(chan int) result := make(chan int) var wg sync.WaitGroup // 提前添加计数,避免Wait提前返回 wg.Add(len(input)) go process_all(input, c, &wg) go sum_results(c, result) wg.Wait() close(c) sum := <-result fmt.Println(sum) } func sum_results(c chan int, res chan int) { var sum int for result := range c { sum += result } res <- sum } func process_all(inputs []int, c chan int, wg *sync.WaitGroup) { for _, num := range inputs { // 忽略索引,正确获取切片元素 go process_input(num, c, wg) } } func process_input(input int, c chan int, wg *sync.WaitGroup) { defer wg.Done() c <- input * 2 }
修复说明
- 将
wg.Add(len(input))移到main函数中,确保在wg.Wait()之前完成计数添加,避免WaitGroup提前结束等待。 - 修改
process_all中的遍历方式为for _, num := range inputs,正确获取切片元素而非索引。 - 移除
process_all中多余的wg.Add(len(inputs)+1)和defer wg.Done(),简化WaitGroup的管理逻辑。
内容的提问来源于stack exchange,提问作者Eduardo Díaz
相关产品推荐
相关产品推荐

