Go语言中执行发送操作的goroutine是否会发生阻塞?
Go无缓冲通道发送阻塞逻辑说明
执行发送操作的goroutine并不是永远不会阻塞,你对无缓冲通道的特性理解是正确的,出现实际运行结果和预期不符的核心原因是对当前代码的执行时序判断有偏差:
- 你的代码中3个发送goroutine分别对应3个独立的无缓冲通道,主goroutine内的
select语句会同时监听这3个通道的接收事件。3个goroutine启动后会立刻尝试向对应通道发送数据,当主goroutine进入select时,3个通道的发送操作都已经处于就绪状态,select会在极短时间内完成所有3条消息的接收和打印,整个过程没有额外等待,之后才会执行sleep操作。 - 你预期的「主goroutine处于sleep状态、未执行接收逻辑时,无缓冲通道的发送方会阻塞」的逻辑完全成立,只是在当前代码的执行流程中,所有发送操作都已经在第一次进入
sleep前完成了接收匹配,自然不会在sleep阶段出现阻塞带来的延迟。 - 你可以通过简单改造代码验证这个逻辑:只保留1个无缓冲通道,启动1个goroutine循环向该通道发送10次数据,主goroutine每次接收到数据后sleep 1秒,此时你可以看到打印间隔恰好为1秒,发送goroutine在主goroutine sleep期间会一直处于阻塞状态,直到主goroutine回到接收逻辑才会继续执行。
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

