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

Go语言死锁问题求助:all goroutines are asleep - deadlock错误排查

代码死锁原因及修复方案

核心死锁问题点

  • goroutine内部错误调用wg.Wait():两个goroutine都属于WaitGroup的计数成员,自身调用wg.Wait()会导致等待自己完成,和main函数的wg.Wait()形成循环阻塞。
  • 无缓冲通道的自发送自接收:ch2是无缓冲通道,第二个goroutine执行ch2 <- value后,没有其他goroutine接收该值,会一直阻塞在发送操作上,后续逻辑无法推进。

修复后的代码

package main

import (
    "fmt"
    "sync"
)

func main() {
    ch1 := make(chan int)
    ch2 := make(chan int)
    var wg sync.WaitGroup

    wg.Add(1)
    go func() {
        defer wg.Done()
        b := 42
        ch1 <- b
        fmt.Println("ch1发送完成,通道地址:", ch1)
        close(ch1)
    }()
    value := <-ch1
    fmt.Println("main接收ch1的值:", value)

    wg.Add(1)
    go func(val int) {
        fmt.Println("进入第二个goroutine,传入值:", val)
        defer wg.Done()
        ch2 <- val
        close(ch2)
    }(value)
    
    // 接收ch2的值,解除goroutine的发送阻塞
    a := <-ch2
    fmt.Println("main接收ch2的值:", a)
    
    wg.Wait()
}

修复说明

  • 移除两个goroutine内部的wg.Wait(),仅在main函数中统一等待所有goroutine完成。
  • 拆分ch2的发送和接收逻辑:由goroutine发送,main函数接收,避免无缓冲通道的自阻塞。
  • 第二个goroutine通过参数传递value,避免闭包变量捕获的潜在问题。
  • 通道关闭操作放在发送完成后执行,保证接收方不会收到无效零值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 14:27:42