Golang select ready channel randomly

·

2 min read

When you have multiple channels ready in a select statement, go will select a ready channel randomly:

For example:

package main

import "fmt"

func main() {
    a := make(chan int, 10)
    b := make(chan int, 10)
    c := make(chan int, 10)

    for i := 0; i < 10; i++ {
        a <- i
        b <- i
        c <- i
    }

    aNum, bNum, cNum := 0, 0, 0

    for i := 0; i < 9; i++ {
        select {
        case <-a:
            aNum++
            fmt.Print("a ")
        case <-b:
            bNum++
            fmt.Print("b ")
        case <-c:
            cNum++
            fmt.Print("c ")
        }
    }
    fmt.Printf(
        "\na selected %d, b selected %d, c selected %d\n",
        aNum,
        bNum,
        cNum,
    )
}

The first part of the code will fill values to our 3 channels, a, b and c, then in the select statement, we run 9 times to let go choose value from those 3 ready channels. We can run this multiple times:

$ go run main.go
b c c b a a c a b 
a selected 3, b selected 3, c selected 3
$ go run main.go
b b b b a c a b b 
a selected 2, b selected 6, c selected 1
$ go run main.go
a b a a b b c c a 
a selected 4, b selected 3, c selected 2

You can see go chose those channels randomly, for example, in the second time, it chose channel b for 6 times while only chose c for 1 time.

We can change the buffer size to 100 and run the select 90 times:

$ go run main.go
a selected 21, b selected 35, c selected 34
$ go run main.go
a selected 35, b selected 27, c selected 28
$ go run main.go
a selected 21, b selected 33, c selected 36
$ go run main.go
a selected 30, b selected 31, c selected 29
$ go run main.go
a selected 30, b selected 33, c selected 27

The last 2 seems pretty fair, every channel get selected around 30 times. But the first 3, some channel get selected 36 times, the other get selected 21 times.

Anyway, the conclusion is, if you have multiple channels ready in a select statement, go will choose them randomly, so your code shouldn't rely on the pick order.

Reference