Go 带缓冲通道的死锁
我有一些代码,它是一个作业调度器,正在整理来自许多TCP套接字的大量数据。这段代码是一种解决方法的结果,它在很大程度上可以降低CPU的使用量,并且锁定现在也不是问题 我的应用程序有时会被锁定,“通道长度”日志是唯一一个不断重复的东西,因为数据仍然从我的套接字传入。然而,计数保持在5000,没有进行下游处理Go 带缓冲通道的死锁,go,goroutine,Go,Goroutine,我有一些代码,它是一个作业调度器,正在整理来自许多TCP套接字的大量数据。这段代码是一种解决方法的结果,它在很大程度上可以降低CPU的使用量,并且锁定现在也不是问题 我的应用程序有时会被锁定,“通道长度”日志是唯一一个不断重复的东西,因为数据仍然从我的套接字传入。然而,计数保持在5000,没有进行下游处理 我认为问题可能是比赛条件,它可能挂断的线路是频道我是新手,但在这里的代码中 case msg := <-inboundFromTCP: log.Println("Got
我认为问题可能是比赛条件,它可能挂断的线路是
频道我是新手,但在这里的代码中
case msg := <-inboundFromTCP:
log.Println("Got packet", msg.Avr)
channel, ok := channelMap[msg.Avr]
if !ok {
packetChan := make(chan *trackingPacket_v1)
channelMap[msg.Avr] = packetChan
go processPackets(packetChan, shutdownChan, msg.Avr)
packetChan <- msg
continue
}
channel <- msg
那么,在添加消息之前,您不需要清空该频道吗
channel <- msg
channel我猜你的问题是在执行此操作时遇到了问题channel在死锁发生时获取堆栈跟踪,并查看每个goroutine被阻止的位置。我尝试过,但有300个左右的goroutine,无法确定块在何处!这里有任何命令可以帮助您吗?如果您处于inboundFromTCP
案例中,并且相应的processPackets
关闭,那么它不会从映射中删除,因此会出现死锁。这有点过度使用频道的味道,但我对这个问题没有清晰的认识,所以我不确定应该把你送到哪个方向。不要听那些讨厌频道的人的话。是的,通道是一个锁,就像互斥锁一样。但是通道架构可以非常好地工作。一旦你找到了你所看到的bug。不,那频道,ok
就是从地图中取出一个存储的频道。如果它不存在,则ok
为false,代码将创建一个频道并将其设置在地图中。感谢您的解释,Zan!我希望人们不要对我的答案投反对票。问这个问题的人还要求看第二双眼睛。我知道我的答案很有可能是错误的,但有时只是帮助别人以不同的方式看待问题,或者考虑他们以前没有想到的事情。Zan Lynx似乎就是这样,因为他的回答似乎表明他开始考虑频道可能存在问题。我上面的评论绝对不应被理解为我试图为Zan的回答赢得信任。他在这方面的知识显然比我渊博得多,我很感谢他给我的解释。我只是说,有时候,即使是错误的答案也会帮助你找到正确的答案,因为他们关注的是一个以前没有考虑过的领域,我认为这不应该受到惩罚。我只是在上举了一个独立的例子,我希望这可能有助于弄清真相!谢谢
channel, ok := channelMap[msg.Avr]
channel <- msg