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

在goroutine中添加select default语句导致channel死锁求助

无缓冲Channel带default的Select导致死锁的原因分析

先拆解你的代码执行全程:

  1. 你创建的是无缓冲Channel,这种Channel的发送操作ch <- 1必须等有接收方(也就是main goroutine里的<-ch)准备好接收,才能完成,否则会阻塞。
  2. 启动的子goroutine用了带default的select:select的规则是,当所有case都无法立即执行时,会直接走default分支,不会阻塞等待。
  3. main goroutine一开始就执行time.Sleep(2),这2秒内完全没准备接收Channel的数据。所以子goroutine跑起来后,ch <-1这个case无法立即执行(没人接),直接触发default,打印完就退出了——根本没往Channel里发数据。
  4. 2秒后main goroutine醒来,执行<-ch尝试接收,但此时Channel是空的,也没有其他goroutine会往里面发数据,main goroutine就一直阻塞在这里。整个程序里所有goroutine都处于休眠等待状态,Go runtime就会抛出死锁错误。

为什么去掉default或time.Sleep(2)就正常?

  • 去掉default:子goroutine里的select会阻塞在ch <-1这个case上,一直等到main goroutine结束休眠、准备好接收。此时发送操作完成,打印send suc,main也能接收到数据,程序正常退出。
  • 去掉time.Sleep(2):main goroutine启动子goroutine后,立刻执行<-ch准备接收。此时子goroutine的ch <-1可以立即完成(因为接收方已经就绪),所以打印send suc,接收也正常,程序无阻塞。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 15:55:37