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

Go HTTP服务器测试并发Rest API时挂起,通道使用异常

问题分析与解决方案

原代码的核心问题

第一个版本里,你用了无缓冲通道chalk,四个协程往通道发送数据,主协程用for range遍历通道接收数据。但for range遍历通道的逻辑是一直等待直到通道被关闭,你没关闭通道,所以主协程会卡在循环里,永远到不了w.Write那行,自然无法返回HTTP响应。

第二个版本的错误更明显:你把close(chalk)和wg.Wait()放在了for range循环之后,但主协程根本走不到这两行——因为for range还在等着通道关闭,直接造成死锁。另外,wg.Wait()应该等所有工作协程都写完数据后,再关闭通道,这样主协程的循环才能正常退出。

正确的修改代码

func concurrent2(w http.ResponseWriter, r *http.Request) {
    chalk := make(chan string)
    var wg sync.WaitGroup

    for i := 0; i < 4; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            log.Print("=>")
            chalk <- "Hello"
        }()
    }

    // 启动单独协程等待所有工作协程完成,然后关闭通道
    go func() {
        wg.Wait()
        close(chalk)
    }()

    fmt.Println("out Of the Loop")
    var message string
    for value := range chalk {
        message += value
        log.Print("Value 2 ", message)
    }

    // 循环退出说明通道已关闭,所有数据都接收完成
    w.Write([]byte(message))
}

关键改动说明

  • 新增一个匿名协程,专门负责等待所有工作协程执行完毕(wg.Wait()),然后关闭通道chalk。
  • 主协程的for range循环会在通道关闭后自动退出,之后就能正常执行w.Write返回响应了。
  • 无缓冲通道在这里可以正常工作:每个工作协程发送数据时,会阻塞到主协程接收数据,不会出现数据丢失的情况。

内容的提问来源于stack exchange,提问作者Ankit Chakraborty

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 18:12:45