Golang Go语言中的通道读取报错问题

发布于 1周前 作者 zlyuanteng 来自 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:=&lt;-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

5 回复

补充:打开注释 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之间进行通信的一种重要机制。如果在读取通道时遇到报错,通常可能是由以下几种原因引起的:

  1. 通道关闭且没有数据:如果尝试从一个已关闭且没有数据的通道中读取,会立即返回该类型的零值,并且不会报错。但如果你使用range关键字读取已关闭的通道,循环会正常结束。

  2. 通道未关闭且已无数据:在一个非缓冲通道上,如果发送方已经关闭或没有更多的数据发送,而接收方还在等待读取,这将导致接收方阻塞,而不是报错。对于缓冲通道,如果缓冲区为空且没有更多的数据发送,同样会导致阻塞。

  3. 通道已被关闭且有数据:这是正常操作,读取会成功直到通道中的数据被完全读取完毕。

  4. 通道操作中的panic:如果发送方或接收方在执行通道操作时发生了panic,这可能导致通道处于不确定状态,接收方可能会遇到无法预期的错误。

解决读取通道报错问题,通常需要检查:

  • 通道是否在使用前已正确初始化。
  • 发送和接收操作是否匹配(包括通道的类型和方向)。
  • 通道是否在适当的时候被关闭。
  • 是否有goroutine泄漏或死锁情况。

确保这些方面正确处理,可以有效避免通道读取时的报错问题。如果问题依旧存在,建议详细检查代码逻辑或使用Go的race detector工具来诊断潜在的并发问题。

回到顶部