dsfykqq3403 2013-09-07 16:42
浏览 50
已采纳

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

To quote from the 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.

How can I wait for more than one channel in a case clause, so that only when both channels return the case is executed?

example:

select {

   case <-ch1, <-ch2 ... : //wait for ch1 and ch2 
        // do something 
   case  ..
}
  • 写回答

1条回答 默认 最新

  • dtsi9484 2013-09-07 17:32
    关注

    There's no way to wait for multiple channels in the same select case, and there's also no way way to "fallthrough" in select cases, as the documentation describes:

    You can easily do something like this via other means, though.

    Without select:

    This only works if c1 is guaranteed to return despite the availability of c2.

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

    With looping:

    This works despite the ordering, but c1 and c2 must only fire once, or it might misbehave:

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

    With goroutines:

    This works either way, but you lose the ordering of results:

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

    With sync.WaitGroup:

    This works either way:

    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
    

    And so on. There are certainly other ways. The best one depends on the details of what you're trying to achieve.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?