【问题标题】:Make the select statement wait for more than one channel at the same time使select语句同时等待多个通道
【发布时间】:2013-09-11 14:30:30
【问题描述】:

引用The Go Programming Language Specification

“选择”语句选择一组可能的通信中的哪一个 将继续。它看起来类似于“switch”语句,但带有 案例都涉及到通信操作。

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

示例

select {

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

【问题讨论】:

    标签: concurrency go channel


    【解决方案1】:

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

    不过,您可以通过其他方式轻松地做这样的事情。

    不选择:

    这仅在 c1 保证返回时有效,尽管 c2 可用。

    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
    

    使用 goroutine:

    这两种方法都可以,但是您会丢失结果的顺序:

    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
    

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

    【讨论】:

      猜你喜欢
      • 2013-09-09
      • 1970-01-01
      • 2019-09-17
      • 1970-01-01
      • 2020-07-30
      • 2015-10-29
      • 1970-01-01
      • 1970-01-01
      • 2012-11-19
      相关资源
      最近更新 更多