简体   繁体   中英

Make the select statement wait for more than one channel at the same time

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  ..
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM