假设我有2个缓冲通道,我如何等待它们,并且只有当两个通道中至少有一个项目时才会继续?
看起来像装配一个有两个部分的机器,只有当两个部分都在手边时我才能继续工作。
Both queue are empty, wait.
-------------------
| | | | QUEUE A
-------------------
-------------------
| | | | QUEUE B
-------------------
Queue A has one element but Queue B empty, wait
-------------------
| | | X | QUEUE A
-------------------
-------------------
| | | | QUEUE B
-------------------
Queue A has two elements but Queue B empty, still wait
-------------------
| | Y | X | QUEUE A
-------------------
-------------------
| | | | QUEUE B
-------------------
Both queue has item in it, consume one from each queue.
-------------------
| | Y | X | QUEUE A
-------------------
-------------------
| | | Z | QUEUE B
-------------------
Now, Queue B empty again, wait ...
-------------------
| | | Y | QUEUE A
-------------------
-------------------
| | | | QUEUE B
-------------------
答案 0 :(得分:2)
从2个频道接收不是原子的。您可以使用内置len()
函数检查通道缓冲区中排队的元素数量,但您无法进行双通道原子接收。
当您从一个频道收到一个频道时,另一个频道可能无法接收(例如,另一个goroutine可能已经从该频道收到)。
如果只有一个goroutine消耗并处理这些值,只需从两个通道接收一个值,如果某个值未就绪(如果通道未准备接收),它将阻止:
v1 := <- ch1
v2 := <- ch2
// process v1 and v2
另请注意,如果频道已关闭,接收也会成功。
答案 1 :(得分:0)
这样的事情怎么样:
type Foo1 struct {}
type Foo2 struct {}
type Combination struct {
foo1 *Foo1
foo2 *Foo2
}
func mergeChan(chIn chan *Foo1, chIn2 chan *Foo2, chOut chan *Combination) {
for foo1 := range chIn {
chOut <- &Combination{
foo1: foo1,
foo2: <-chIn2,
}
}
}
聆听chOut,您将始终收到两个频道的组合。