1 回答
TA贡献2011条经验 获得超2个赞
你有一个死锁,因为你的偶数和奇数 goroutines 在发送到时被阻止,out因为没有从中读取任何内容。为什么什么都不读out?因为maingoroutine 在发送到时被阻止,input因为没有从中读取任何内容。为什么没有读取input?因为从中读取的两个 goroutine 被阻塞了。
此外,除非您将它们的内容包装在其中,否则它们filterEven和filterOdd都只会运行一次for { }(但是在您之前它们永远不会停止break)。另一方面,当没有任何东西可以写入时,range even将阻塞(并且range odd永远不会发生)even,因为range只有当通道关闭或被break调用时,通道才会停止。
一般来说,只要您知道何时可以关闭通道,这些都不是很难解决的问题。根据您的描述,这变得更加困难。没有一个 goroutine 知道什么时候可以关闭input,因为所有三个都向它写入,两个也从它读取。您可以使用 async.WaitGroup来确保input在关闭之前已处理您放入通道的所有内容。一旦它关闭,另外两个 goroutine 就可以使用它作为关闭它们自己的通道break或return完成运行的信号。
但是,对in和out通道的写入仍然会阻塞,直到有相应的读取,因为它们是无缓冲的。但是,如果您通过将大小指定为 的第二个参数来缓冲它们,则make在通道已满之前不会阻止写入。既然你既不知道even或odd将有更多的写入他们比什么main送input,你可以使用它作为安全缓冲能力。
这是WaitGroup为您的代码使用带缓冲通道的示例:https : //play.golang.org/p/VXqfwUwRcx
如果您不想要缓冲通道,您还可以使用另一对 goroutines 来捕获值并main在完成后将它们作为切片发送回。这种方式写在even和odd渠道不会阻塞:https://play.golang.org/p/i5vLDcsK1v
否则,如果不需要一次打印每个频道的内容,您可以使用这两个额外的 goroutine 从频道中读取并立即打印:https : //play.golang.org/p/OCaUTcJkKB
- 1 回答
- 0 关注
- 163 浏览
添加回答
举报
