Go通道报错:向已关闭通道发送数据的原因排查
错误原因分析:send on closed channel
你的猜测完全正确,这个"send on closed channel"的panic确实是多个goroutine同时尝试向已关闭的outputCh发送数据导致的,具体触发流程如下:
- 第一个完成任务的goroutine成功将数据发送到
outputCh,main函数的select立刻命中case output := <-outputCh分支,随即执行close(stopCh)和close(outputCh)操作。 - 但此时,有部分goroutine已经通过了
request函数里的select检查:它们在stopCh被关闭前就执行到了select语句,命中default分支,已经跳过了stopCh的判断,正准备执行*outputCh <- &testStr的发送操作。 - 当这些goroutine实际执行发送时,
outputCh已经被main函数关闭,而Go语言中向已关闭的通道发送数据会直接触发panic,这就是你看到的错误的根源。
补充说明代码里的关键问题:
stopCh是无缓冲通道,关闭它后,后续的<-*stopChan会立即返回,但对于那些已经走到default分支的goroutine,这个关闭操作无法中断它们后续的发送逻辑。request函数里的select是非原子操作,检查stopCh和执行发送这两步之间没有同步机制,导致竞态条件出现。
内容的提问来源于stack exchange,提问作者BoredGeek
相关产品推荐
相关产品推荐

