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

一个 go 的通道读取报错问题

  •  
  •   yagamil · 40 天前 · 346 次点击
    这是一个创建于 40 天前的主题,其中的信息可能已经有所发展或是发生改变。
    package main
    
    import (
    	"time"
    )
    
    func main() {
    	num:=20
    	var ch_data chan int = make(chan int, num)
    	go func() {
    		for i := 0; i < num; i++ {
    			ch_data <- i
    			time.Sleep(time.Millisecond*100)
    		}
    		//close(ch_data)
    	}()
    
    	println("waiting for data")
    
    	for {
    		data,ok:=<-ch_data
    		if !ok{
    			break
    		}
    		println("通道数据",data)
    	}
    }
    

    如果把读取通道的次数限定次数后,不会报错:

    for i:=0;i<num;i++{
    		data,ok:=<-ch_data
    		if !ok{
    			break
    		}
    		println(ok)
    		println("通道数据",data)
    	}
    

    请问各路大神, 造成这个问题 是不是因为 data,ok:=<-ch_data 在通道满了之后不能这样读?

    yagamil
        1
    yagamil   40 天前
    补充:打开注释 close(ch_data) 也是可以正常运行的。
    mainjzb
        2
    mainjzb   40 天前
    waiting for data
    通道数据 0
    通道数据 1
    通道数据 2
    通道数据 3
    通道数据 4
    通道数据 5
    通道数据 6
    通道数据 7
    通道数据 8
    通道数据 9
    通道数据 10
    通道数据 11
    通道数据 12
    通道数据 13
    通道数据 14
    通道数据 15
    通道数据 16
    通道数据 17
    通道数据 18
    通道数据 19
    fatal error: all goroutines are asleep - deadlock!


    符合预期输出。有啥问题
    mangoDB
        3
    mangoDB   40 天前   ❤️ 1
    原因是 chan 中的所有数据读完之后,程序会阻塞在读 chan 阶段,然后程序报错「 all goroutines are asleep - deadlock!」,即无论阻塞多久,也不有任何改变。

    将 chan close 之后,读取空 chan 会返回 false,然后正常跳出循环。
    yagamil
        4
    yagamil   40 天前
    @mangoDB 谢谢大神回复!
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1095 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 22:05 · PVG 06:05 · LAX 14:05 · JFK 17:05
    ♥ Do have faith in what you're doing.