如何等待 2 个通道并在它们都准备好读取时继续
how to wait on 2 channels and continue when they are both ready for read
假设我有 2 个缓冲通道,我如何等待它们,并且只有在两个通道中至少有一个项目时才继续?
看起来assemble一台机器有两个部分,只有两个部分都在手边,我才能继续工作。
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
-------------------
从 2 个通道接收不是原子的。您可以使用内置 len()
函数检查通道缓冲区中排队的元素数量,但您不能执行 2 通道原子接收。
意思是当您从一个通道接收到值时,另一个通道可能还没有准备好接收(例如,另一个 goroutine 可能已经从它接收到)。
如果只有一个 goroutine 消费和处理这些值,简单地从两个通道接收一个值,如果一个值没有准备好它会阻塞(如果通道没有准备好接收):
v1 := <- ch1
v2 := <- ch2
// process v1 and v2
另请注意,如果频道关闭,接收也会成功。
这样的事情怎么样:
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 时,您总是会收到来自两个频道的组合。
假设我有 2 个缓冲通道,我如何等待它们,并且只有在两个通道中至少有一个项目时才继续?
看起来assemble一台机器有两个部分,只有两个部分都在手边,我才能继续工作。
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
-------------------
从 2 个通道接收不是原子的。您可以使用内置 len()
函数检查通道缓冲区中排队的元素数量,但您不能执行 2 通道原子接收。
意思是当您从一个通道接收到值时,另一个通道可能还没有准备好接收(例如,另一个 goroutine 可能已经从它接收到)。
如果只有一个 goroutine 消费和处理这些值,简单地从两个通道接收一个值,如果一个值没有准备好它会阻塞(如果通道没有准备好接收):
v1 := <- ch1
v2 := <- ch2
// process v1 and v2
另请注意,如果频道关闭,接收也会成功。
这样的事情怎么样:
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 时,您总是会收到来自两个频道的组合。