使select语句同时等待多个通道

时间:2013-09-07 16:42:04

标签: concurrency go channel

引用The Go Programming Language Specification

  

“select”语句选择一组可能的通信中的哪一个   将继续它看起来类似于“切换”语句,但与   所有案件都涉及通信业务。

如何在case子句中等待多个通道,以便只有当两个通道都返回时才会执行?

示例

select {

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

1 个答案:

答案 0 :(得分:4)

在相同的选择案例中无法等待多个频道,并且在选择的情况下也无法“突破”,正如文档所述:

但是,你可以通过其他方式轻松做到这一点。

没有选择:

只有在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

等等。当然还有其他方法。最好的一个取决于你想要达到的细节。