Go语言无缓冲通道主协程传值死锁多案例原因咨询
问题1解答
你的猜测完全正确,核心逻辑基于Go语言无缓冲通道的基础特性:无缓冲通道的发送操作会永久阻塞,直到有其他goroutine对该通道执行接收操作。
- case1:整个程序只有main这1个goroutine,往无缓冲通道发数据时没有任何其他goroutine接收,main goroutine永久阻塞,所有goroutine都进入休眠状态,触发死锁。
- case2:启动的子goroutine拿到通道后没有执行任何接收操作就直接退出,发送
1时还是没有可用的接收方,main goroutine依然永久阻塞,触发死锁。 - case3:子goroutine明确执行了
<-ch的接收操作,main goroutine发送1时数据被子goroutine正常接收,两边都不会阻塞,程序执行完正常退出,没有死锁。
问题2解答
两者的核心差异是子goroutine的通道接收能力不同:
- case4:子goroutine只会执行1次接收操作,第一次发送
1时数据被正常接收,接收完成后子goroutine直接退出,后续发送2时又没有可用的接收方,main goroutine阻塞在第二次发送操作上,触发死锁。 - case5:子goroutine通过
for{}死循环持续执行通道接收操作,不管往通道发多少个数据,都有对应的接收方处理,所有发送操作都不会阻塞,main goroutine发完5个数据后正常执行结束,程序退出,不会触发死锁。(注:main goroutine退出时会直接终止所有仍在运行的子goroutine,所以子goroutine的死循环不会带来资源泄漏问题)
内容的提问来源于stack exchange,提问作者syoui jyo
相关产品推荐
相关产品推荐

