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

2021-10-21 10:04:49 +08:00
 yagamil
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 在通道满了之后不能这样读?

739 次点击
所在节点    Go 编程语言
4 条回复
yagamil
2021-10-21 10:18:15 +08:00
补充:打开注释 close(ch_data) 也是可以正常运行的。
mainjzb
2021-10-21 10:22:06 +08:00
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
2021-10-21 10:24:11 +08:00
原因是 chan 中的所有数据读完之后,程序会阻塞在读 chan 阶段,然后程序报错「 all goroutines are asleep - deadlock!」,即无论阻塞多久,也不有任何改变。

将 chan close 之后,读取空 chan 会返回 false,然后正常跳出循环。
yagamil
2021-10-21 10:28:02 +08:00
@mangoDB 谢谢大神回复!

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

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

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

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

© 2021 V2EX