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

如何正确关闭Channel以解决Go程序死锁问题?

解决goccm限制goroutine时的通道死锁问题

你的代码死锁确实是因为chanStr没关闭,而且c.WaitAllDone()的位置错了——for range chanStr会一直阻塞等待通道关闭,后面的c.WaitAllDone()根本跑不到,导致程序卡死。

利用goccm自带的等待机制,我们可以把关闭通道的逻辑放到一个单独的goroutine里,避免阻塞主goroutine的接收循环。修改后的代码如下:

func main() {
    c := goccm.New(5)
    chanStr := make(chan string)
    lines := []string{"aaaaaa", "fffff", "ddddd", "eeeee"}

    for _, value := range lines {
        value := value
        c.Wait()
        go func() {
            chanStr <- value
            c.Done()
        }()
    }

    // 单独起goroutine等待所有任务完成后关闭通道
    go func() {
        c.WaitAllDone()
        close(chanStr)
    }()

    // 遍历接收数据,通道关闭后自动退出循环
    for value := range chanStr {
        fmt.Println(value)
    }
}

关键改动说明:

  • 新增的goroutine专门负责等待所有并发任务执行完毕,随后关闭chanStr,这样主goroutine的for range循环在接收完所有数据后,会因为通道关闭而正常退出。
  • 不需要额外维护done通道,goccm的WaitAllDone()已经帮你处理了等待所有goroutine完成的逻辑。

内容的提问来源于stack exchange,提问作者sheki meki

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 22:57:11