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
相关产品推荐
相关产品推荐

