go-runtime 不会将对象推出缓冲通道
Posted
技术标签:
【中文标题】go-runtime 不会将对象推出缓冲通道【英文标题】:go-runtime doesn't push the object out of the buffered channel 【发布时间】:2021-10-08 15:44:30 【问题描述】:我有一个自定义类型的缓冲通道(用户定义的结构)。偶尔我会看到虽然推送到频道中的对象没有被接收到。
在 delve 调试器中当我打印通道时,我看到 1/100,这意味着通道中存在一个对象。此外,正在观看该频道的 go 例程正在运行(在 delve 调试器中转储的 go 例程列表中可见)。 Go-Runtime 是否存在已知问题?
示例代码:-
func sender()
myChan := make(chan mystruct, 10)
myChan <- mystruct
app.Debug(appctx.LogTagGen, "Posted mystruct to myChan")
func goroutinereceiver()
for
select
case mystruct := <-myChan:
funcx(mystruct)
我可以在日志中看到消息“已将 mystruct 发布到 myChan”。此外,在 delve 调试器中,我可以打印此通道以查看通道中存在的对象。另外,我看到接收器 goroutine 正在运行:-
(dlv) 打印 myChan :- myChan mystruct: chan *mystruct 1/100
【问题讨论】:
但是如果问题中没有正确的数据,则关闭问题是解决方案(问题的)。见How to Ask。 Go 运行时中的基本结构之一极不可能以这种方式被破坏,并且您是唯一遇到它的人。您看到的行为可能还有其他原因,需要minimal reproducible example 来调试它。如果您可以在运行时使用通道重现错误,那么您应该将其作为问题提交给 Go 团队。 再次,没有没有问题。运行时没有这个错误。如果通道发送和接收没有按照您认为的方式工作,那么您的 代码 或您对发送/接收的理解 错误或不匹配。 @Hemanth 您的问题直截了当地说“Go-Runtime 是否存在已知问题?”这肯定会让您觉得 Go 运行时可能存在问题。在跟上 Go 一段时间后,我可以自信地说,目前没有,多年来也没有像这样的通道发送/接收问题。但要对诊断此类问题有任何希望,您需要提供代码来重现它,以及 Go 版本、操作系统和架构。 看看你的代码中可能出现的问题,并且没有通过通道“推送”的概念,开始的地方是确认通道接收器的状态并检查基本的逻辑错误。例如,如果routingApp.handleBgpConfigEvent
有任何阻塞的机会,则该循环可能永远不会收到另一个值。
【参考方案1】:
发现问题:- 每当接收 goroutine 在创建通道的 goroutine 之前执行时。当接收到“nil 通道”时,接收 go 例程将进入无限期休眠。这就是问题所在。尽管通道是稍后创建的,但接收 goroutine 已经处于无限期休眠状态!该问题并未持续出现,因为它取决于首先调度哪个 goroutine。
【讨论】:
以上是关于go-runtime 不会将对象推出缓冲通道的主要内容,如果未能解决你的问题,请参考以下文章