1 回答
TA贡献2011条经验 获得超2个赞
你有一个死锁,因为你的偶数和奇数 goroutines 在发送到时被阻止,out
因为没有从中读取任何内容。为什么什么都不读out
?因为main
goroutine 在发送到时被阻止,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 关注
- 129 浏览
添加回答
举报