【发布时间】:2016-04-05 18:35:11
【问题描述】:
我正在尝试创建两个单独的消费者 go 例程,这将过滤掉输入通道中的偶数和奇数。这只是一个玩具示例,目的是看看是否有可能让消费者对从输入通道读取的消息执行某些操作,如果它符合特定条件,则将其放回输入通道。
我目前的代码如下:
package main
func filterOdd(ch chan int, out chan int) {
val := <- ch
if val % 2 == 0 {
ch <- val
} else {
out <- val
}
}
func filterEven(ch chan int, out chan int) {
val := <- ch
if val % 2 != 0 {
ch <- val
} else {
out <- val
}
}
func main() {
even := make(chan int)
odd := make(chan int)
input := make(chan int)
go filterOdd(input, odd)
go filterEven(input, even)
for i:=1; i <= 10; i++ {
input <- i
}
println("Even...")
for i := range even {
println(i)
}
println("Odd...")
for i := range odd {
println(i)
}
}
但是,这会产生以下输出:
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
/tmp/sandbox594577124/main.go:27 +0x140
goroutine 4 [chan send]:
main.filterOdd(0x10336100, 0x103360c0)
/tmp/sandbox594577124/main.go:8 +0xc0
created by main.main
/tmp/sandbox594577124/main.go:24 +0xc0
Go Playground 链接:https://play.golang.org/p/9RIvFsGKI-
【问题讨论】:
-
@ZanLynx:虽然这个问题说他们在示例代码中遇到了死锁,但听起来他们并没有尝试做与其他问题相同的事情。
-
@JamesHenstridge 当然不是一回事。但看起来这个问题的一般问题和解决方案是相同的。
-
而且我刚刚注意到,即使你修复了缓冲,你的 for 循环也不在 goroutines 中,因此会阻塞,除非你总是让缓冲区大于循环大小。