Golang Go语言中大佬帮看一下代码,为什么会偶尔报错 panic: send on closed channel
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
不是你自己 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 < 5; i++ {<br><br> i := i<br> go func() {<br> ch <- 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。
解决这类问题,你可以考虑以下几个方向:
-
确保通道的正确关闭:只在所有发送操作完成后,且确定不会再有发送操作时关闭通道。
-
使用select语句进行发送:通过
select
语句发送数据到通道时,可以添加一个默认case来检测通道是否已关闭,从而避免panic。 -
通道关闭通知:可以通过一个额外的信号通道来通知其他goroutine通道即将关闭,这样它们可以在尝试发送之前检查该信号。
-
调试和日志:增加日志输出,记录通道的打开和关闭时间,以及哪些goroutine在进行发送和接收操作,这有助于追踪问题发生的上下文。
-
使用互斥锁(Mutex)或条件变量(Cond):如果逻辑复杂,可能需要使用这些同步原语来确保对通道操作的正确顺序。
总之,处理这类并发错误的关键在于确保所有对通道的操作都是安全的,并且各个goroutine之间有良好的同步机制。希望这些建议能帮助你解决问题。