You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 20:17:27