Golang Go语言中大佬帮看一下代码,为什么会偶尔报错 panic: send on closed channel

发布于 1周前 作者 phonegap100 来自 Go语言

Golang Go语言中大佬帮看一下代码,为什么会偶尔报错 panic: send on closed channel

func main() {
ch := make(chan int)

for i := 0; i < 5; i++ {

	i := i
	go func() {
		ch <- i
		close(ch)
	}()

}

for c := range ch {
	println(c)
}

}


更多关于Golang Go语言中大佬帮看一下代码,为什么会偶尔报错 panic: send on closed channel的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

11 回复

不是你自己 close 的么?

更多关于Golang Go语言中大佬帮看一下代码,为什么会偶尔报错 panic: send on closed channel的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


close(ch)

你关了 5 次 ch,看 6 个 Goroutine 的调度顺序,只要有 一个 ch <- i 在 close 之后执行,就 panic

你肯定会问为什么有时候会正常退出,因为在 close 之后,range ch 先执行,然后 main 退出,其它 ch <- i 没有被执行到

改一下:
<br>func main() {<br> ch := make(chan int)<br> var wg sync.WaitGroup<br> wg.Add(5)<br> go func() {<br> wg.Wait()<br> close(ch)<br> }()<br><br> for i := 0; i &lt; 5; i++ {<br><br> i := i<br> go func() {<br> ch &lt;- i<br> wg.Done()<br> }()<br><br> }<br><br> for c := range ch {<br> println(c)<br> }<br>}<br>

这代码格式化我裂开了,还是直接贴链接吧: https://play.golang.org/p/kY32r_P92Gh

你不能保证两个循环谁先结束

这是自己都没搞懂代码逻辑。。

娜塔莉的头像

是的 确实是这样

谢谢,这个解决了问题,我原来的测试代码写的其实是有问题的

谢谢大家的分析!

在Go语言中遇到“panic: send on closed channel”错误通常意味着你试图向一个已经被关闭的通道(channel)发送数据。这种情况通常发生在并发编程中,当多个goroutine操作同一个通道时,如果没有正确协调通道的关闭和发送操作,就可能触发这个panic。

解决这类问题,你可以考虑以下几个方向:

  1. 确保通道的正确关闭:只在所有发送操作完成后,且确定不会再有发送操作时关闭通道。

  2. 使用select语句进行发送:通过select语句发送数据到通道时,可以添加一个默认case来检测通道是否已关闭,从而避免panic。

  3. 通道关闭通知:可以通过一个额外的信号通道来通知其他goroutine通道即将关闭,这样它们可以在尝试发送之前检查该信号。

  4. 调试和日志:增加日志输出,记录通道的打开和关闭时间,以及哪些goroutine在进行发送和接收操作,这有助于追踪问题发生的上下文。

  5. 使用互斥锁(Mutex)或条件变量(Cond):如果逻辑复杂,可能需要使用这些同步原语来确保对通道操作的正确顺序。

总之,处理这类并发错误的关键在于确保所有对通道的操作都是安全的,并且各个goroutine之间有良好的同步机制。希望这些建议能帮助你解决问题。

回到顶部