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

Go使用带缓冲通道出现all goroutines are asleep死锁问题求助

问题诊断

你对缓冲通道的基础使用没有问题,死锁的核心原因是通道关闭时机错误,触发了main goroutine的永久阻塞:

  1. 你把close(valueChannel)放在了main函数的defer中,defer只会在main函数执行结束前才会触发
  2. main函数里的for循环会一直尝试从valueChannel读数据,只有通道被关闭时才会收到ok=false的信号跳出循环
  3. 10个goroutine写完10条数据全部退出后,main goroutine读完10条数据后还会继续尝试读通道,此时通道没有被关闭也没有新数据写入,main goroutine永久阻塞,就触发了所有goroutine都休眠的死锁错误
修复方案

调整通道关闭逻辑即可:

  • 移除main函数的defer close(valueChannel)
  • 新增独立goroutine等待所有写goroutine结束后主动关闭通道

修复后的代码如下:

import (
    "fmt"
    "math/rand"
    "sync"
    "time"
)

func main() {
    valueChannel := make(chan int, 2)
    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go doNothing(&wg, valueChannel)
    }

    // 所有写操作完成后关闭通道
    go func() {
        wg.Wait()
        close(valueChannel)
    }()

    // 可以直接用for range遍历通道,通道关闭后自动退出循环
    for v := range valueChannel {
        fmt.Println(v)
    }
}

func doNothing(wg *sync.WaitGroup, numChan chan int) {
    defer wg.Done()
    time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond)
    numChan <- 12
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 01:45:04