V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
qiqiyeshi
V2EX  ›  Go 编程语言

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

  •  
  •   qiqiyeshi · 2020-09-14 10:37:48 +08:00 · 2707 次点击
    这是一个创建于 1521 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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)
    	}
    
    
    }
    
    第 1 条附言  ·  2020-09-14 14:17:04 +08:00

    这个代码片段其实是有问题的, 下面贴上相对合理的代码

    	ch := make(chan int)
    
    
    	go func() {
    		for i := 0; i < 5; i++ {
    			ch <- i
    
    		}
    		close(ch)
    	}()
    
    
    	for c := range ch {
    		println(c)
    	}
    
    10 条回复    2020-09-14 14:18:57 +08:00
    996635
        1
    996635  
       2020-09-14 11:28:09 +08:00
    不是你自己 close 的么?
    zwpaper
        2
    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
        3
    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
        4
    monkeyWie  
       2020-09-14 11:38:44 +08:00
    这代码格式化我裂开了,还是直接贴链接吧: https://play.golang.org/p/kY32r_P92Gh
    raaaaaar
        5
    raaaaaar  
       2020-09-14 12:10:12 +08:00 via Android
    你不能保证两个循环谁先结束
    araraloren
        6
    araraloren  
       2020-09-14 13:28:15 +08:00
    这是自己都没搞懂代码逻辑。。
    MajorAdam
        7
    MajorAdam  
       2020-09-14 13:30:29 +08:00
    娜塔莉的头像
    qiqiyeshi
        8
    qiqiyeshi  
    OP
       2020-09-14 14:11:29 +08:00
    @zwpaper 是的 确实是这样
    qiqiyeshi
        9
    qiqiyeshi  
    OP
       2020-09-14 14:12:39 +08:00
    @monkeyWie 谢谢,这个解决了问题,我原来的测试代码写的其实是有问题的
    qiqiyeshi
        10
    qiqiyeshi  
    OP
       2020-09-14 14:18:57 +08:00
    谢谢大家的分析!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5729 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 03:22 · PVG 11:22 · LAX 19:22 · JFK 22:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.