Golang频道让节目无限期地等待

时间:2014-07-10 16:55:55

标签: go channel

我正在开发一个具有经理/工人风格设置的程序。它有n个工作者从http源获取数据,将数据推送到gameData通道,从urlData通道中提取url信息并重复。然后我有一个goroutine,它应该解析来自api的数据,它从频道gameData中提取并将url推送到urlData频道。

我的问题是,第二次goroutine尝试将某些东西推到其中一个频道上,goroutine停止了,我必须杀死该程序。

以下是代码的一些代码和链接:https://github.com/gaigepr/lolTeams

编辑:

在阅读有关使用缓冲通道的评论后,问题显然是死锁。但是,使通道缓冲只会使死锁花费更长的时间。

此时正在同步解析器和getgames线程以确保没有死锁?

EDIT2:

我重构了程序,现在我使用线程安全队列来存储summonerID,以及每个工作线程现在都在自己的数据上调用解析器函数。这简化了一些好方法。我之所以这样做是因为我无法在玩家周围工作,因为数据累积的性质最终会填满。除非有人有理由不这样做,否则我会留下这个问题,看看是否有人有解决渠道问题的答案。

4 个答案:

答案 0 :(得分:2)

我没有仔细研究过你的长代码片段,但我怀疑你是在没有读取它的情况下推送到频道,所以频道会填满,最终你的推送将无限期地开始阻塞。

如果您需要更好的帮助,我建议发布一个简单的程序(约20行)来重现问题,以便我们可以在http://golang.org上自行运行。

答案 1 :(得分:2)

让我建议一下,您可以使用default案例,例如

default: 
 continue

它可以帮助您处理以前指定的频道中没有传入值的情况,因此您可以简单地继续for循环直到频道出现问题,或者您可以使用像这样:

case <-time.After(6 * time.Second):
 continue

当然,这2个案例将允许您继续循环通过频道,技术上您不会遇到死锁,除非其他常规例程停止通过频道发送值。

答案 2 :(得分:2)

这两个操作可能会相互等待并导致死锁:

gameChan&LT; -game

playerChan&LT; -summonerID

这可以通过将切片(或链接列表)放入其中一个go例程来存储累积数据来解决。使频道缓冲无济于事,因为它受到尺寸的限制。

像这样:http://play.golang.org/p/ZtiPkEoPI6

答案 3 :(得分:0)

问题在于我收集的数据的性质。最终玩家可能会填满导致的死锁。我最终重构并使用了线程安全队列,结果非常好。