concurrency - 使select语句同时等待多个 channel

标签 concurrency go channel

引用自The Go Programming Language Specification :

A "select" statement chooses which of a set of possible communications will proceed. It looks similar to a "switch" statement but with the cases all referring to communication operations.

如何在 case 子句中等待多个 channel ,以便仅当两个 channel 都返回时才执行 case?

示例:

select {

   case <-ch1, <-ch2 ... : //wait for ch1 and ch2 
        // do something 
   case  ..
}

最佳答案

没有办法在同一个选择案例中等待多个 channel ,也没有办法在选择案例中“失败”,如文档所述:

不过,您可以通过其他方式轻松完成此类操作。

没有选择:

尽管 c2 可用,但仅当 c1 保证返回时才有效。

v1 := <-c1
v2 := <-c2

带循环:

尽管有顺序,这仍然有效,但 c1 和 c2 只能触发一次,否则可能会出现错误:

var v1, v2 int
for i := 0; i < 2; i++ {
    select {
    case v1 = <-c1:
    case v2 = <-c2:
    }
}
// both v1 and v2 are set here

使用 goroutines:

这两种方式都有效,但是你失去了结果的顺序:

c3 := make(chan int, 2)
go func() { c3 <- (<-c1) }()
go func() { c3 <- (<-c2) }()

first := <-c3
second := <-c3

使用 sync.WaitGroup:

这两种方式都有效:

var wg sync.WaitGroup
var v1, v2 int
wg.Add(2)
go func() {
    v1 = <-c1
    wg.Done()
}()
go func() {
    v2 = <-c2
    wg.Done()
}()
wg.Wait()
// v1 and v2 are both set

等等。当然还有其他方法。最好的取决于您要实现的目标的细节。

关于concurrency - 使select语句同时等待多个 channel ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18675573/

相关文章:

java - 如何获取预定事件与 JavaFX GUI 交互

java - Java 可以原子地修改两个或更多对象吗?

go - 尝试安装 BEEGO 时出错

go - 如何在 travis-ci 上使用远程包 |走

go - 同时将来自流的字节发送到两个目的地

javascript - 在 chrome 扩展中使用 channel google app engine

java - 为什么这段Java代码没有并发运行

java - 这把锁到底有什么用呢?

json - 如何读取多个json文件

go - 为什么所有的 goroutines 都在 sleep - 僵局。识别瓶颈