Golang Go语言中的通道读取报错问题
Golang Go语言中的通道读取报错问题
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 在通道满了之后不能这样读?
更多关于Golang Go语言中的通道读取报错问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
补充:打开注释 close(ch_data) 也是可以正常运行的。
更多关于Golang Go语言中的通道读取报错问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
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!
符合预期输出。有啥问题
原因是 chan 中的所有数据读完之后,程序会阻塞在读 chan 阶段,然后程序报错「 all goroutines are asleep - deadlock!」,即无论阻塞多久,也不有任何改变。
将 chan close 之后,读取空 chan 会返回 false,然后正常跳出循环。
谢谢大神回复!
在Go语言中,通道(channel)是用于在不同的goroutine之间进行通信的一种重要机制。如果在读取通道时遇到报错,通常可能是由以下几种原因引起的:
-
通道关闭且没有数据:如果尝试从一个已关闭且没有数据的通道中读取,会立即返回该类型的零值,并且不会报错。但如果你使用
range
关键字读取已关闭的通道,循环会正常结束。 -
通道未关闭且已无数据:在一个非缓冲通道上,如果发送方已经关闭或没有更多的数据发送,而接收方还在等待读取,这将导致接收方阻塞,而不是报错。对于缓冲通道,如果缓冲区为空且没有更多的数据发送,同样会导致阻塞。
-
通道已被关闭且有数据:这是正常操作,读取会成功直到通道中的数据被完全读取完毕。
-
通道操作中的panic:如果发送方或接收方在执行通道操作时发生了panic,这可能导致通道处于不确定状态,接收方可能会遇到无法预期的错误。
解决读取通道报错问题,通常需要检查:
- 通道是否在使用前已正确初始化。
- 发送和接收操作是否匹配(包括通道的类型和方向)。
- 通道是否在适当的时候被关闭。
- 是否有goroutine泄漏或死锁情况。
确保这些方面正确处理,可以有效避免通道读取时的报错问题。如果问题依旧存在,建议详细检查代码逻辑或使用Go的race detector工具来诊断潜在的并发问题。