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

2020-09-14 10:37:48 +08:00
 qiqiyeshi
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)
	}


}
2488 次点击
所在节点    Go 编程语言
10 条回复
996635
2020-09-14 11:28:09 +08:00
不是你自己 close 的么?
zwpaper
2020-09-14 11:33:19 +08:00
`close(ch)`

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

你肯定会问为什么有时候会正常退出,因为在 close 之后,range ch 先执行,然后 main 退出,其它 ch <- i 没有被执行到
monkeyWie
2020-09-14 11:35:32 +08:00
改一下:
```
func main() {
ch := make(chan int)
var wg sync.WaitGroup
wg.Add(5)
go func() {
wg.Wait()
close(ch)
}()

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

i := i
go func() {
ch <- i
wg.Done()
}()

}

for c := range ch {
println(c)
}
}
```
monkeyWie
2020-09-14 11:38:44 +08:00
这代码格式化我裂开了,还是直接贴链接吧: https://play.golang.org/p/kY32r_P92Gh
raaaaaar
2020-09-14 12:10:12 +08:00
你不能保证两个循环谁先结束
araraloren
2020-09-14 13:28:15 +08:00
这是自己都没搞懂代码逻辑。。
MajorAdam
2020-09-14 13:30:29 +08:00
娜塔莉的头像
qiqiyeshi
2020-09-14 14:11:29 +08:00
@zwpaper 是的 确实是这样
qiqiyeshi
2020-09-14 14:12:39 +08:00
@monkeyWie 谢谢,这个解决了问题,我原来的测试代码写的其实是有问题的
qiqiyeshi
2020-09-14 14:18:57 +08:00
谢谢大家的分析!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/706782

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX