无缓冲channel一发就死锁因其是同步通道发送操作会立即阻塞必须有另一goroutine同时执行接收操作才能配对完成否则所有goroutine休眠触发deadlock。无缓冲 channel 为什么一发就死锁因为它是同步通道ch 这一行会卡死直到有另一个 a stylecolor:#f60; text-decoration:underline; titlego hrefhttps://www.php.cn/zt/15863.html target_blankgo/aroutine 正好在执行 code。主 goroutine 自己不启接收协程又没配对结果所有 goroutine 都 asleep直接报 codefatal error: all goroutines are asleep - deadlock!。必须配对一个 goroutine 发至少一个 goroutine 收不能是同一个 goroutine 先发后收调试时加 fmt.Println(before send) 和 fmt.Println(after send)如果只看到前一句基本就是卡在发送上了适合场景goroutine 启动通知、任务完成信号、精确控制执行节奏比如等某件事做完再继续用 channel 做“完成信号”怎么写才安全别用 ch : make(chan int) 然后 ch 就完事——接收端没启动必死锁。正确做法是让 sender 和 receiver 在不同 goroutine 中且 receiver 要提前或同步就位。典型模式sender 发一个零值如 struct{}{}receiver 用 阻塞等待用 chan struct{} 而不是 chan int省空间、语义清、零值无歧义关闭通道不是必须的若要用只由 sender 关闭receiver 绝不调 close(ch)go func() { doWork() ch - struct{}{} // 通知完成}()-ch // 主 goroutine 等在这里select default 为什么比纯阻塞更适合信号场景纯 会无限等待一旦信号没来程序就卡住。而 codeselect 可以加超时或非阻塞兜底避免逻辑僵死。default 分支让接收变成“尝试读”不阻塞适合轮询或降级处理搭配 time.After 可实现带超时的等待防止依赖方失联拖垮主流程注意select 是随机选就绪分支多个 case 都 ready 时不会按顺序执行select {case -done: fmt.Println(收到完成信号)default: fmt.Println(没等到信号继续干别的)}channel 关闭后还能读吗怎么判断是不是真关了能读但行为分情况无缓冲 channel 关闭后读立刻返回零值 false有缓冲 channel 关闭后先读完缓存数据之后才返回零值 false。 Mokker AI AI产品图添加背景