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

遍历未关闭通道引发死锁却未触发Panic?计时器为何影响该行为

为什么Go中计时器会阻止死锁Panic?

首先要明确Go的死锁触发逻辑:Go的死锁panic只会在所有goroutine都处于阻塞状态,且没有任何goroutine能继续推进程序执行时才会触发。

无计时器的场景

移除计时器后,程序执行流程如下:

  • 向缓冲通道channel1存入两个元素
  • for range遍历通道,取完两个元素后,会持续阻塞在channel1的读取操作上(通道未关闭,遍历会一直等待新数据)
  • 此时程序中只有main这一个goroutine,它完全阻塞,没有其他goroutine能运行,满足死锁检测条件,因此Go runtime触发死锁panic。

有计时器的场景

保留计时器时,关键差异在于time.NewTicker的行为:

  • time.NewTicker会启动一个后台goroutine,这个goroutine会按设定的500ms间隔,持续向limiter.C通道发送时间值
  • 当main goroutine取完channel1的两个元素后,会阻塞在channel1的读取上,但后台的计时器goroutine仍在正常运行(不断生成时间事件发送到limiter.C)
  • 因为存在活跃的goroutine(计时器的后台goroutine),Go runtime判定程序还有继续执行的可能,不会触发死锁panic,程序因此无限挂起。

额外补充:如果在代码中调用limiter.Stop(),会停止计时器的后台goroutine,此时所有goroutine都进入阻塞状态,程序就会触发死锁panic。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 12:25:35