关于select结构中代码执行公平性的疑问

1.关于select选择通道公平性的描述

在有关select条件选择的执行原则中有这样一句描述“如果多个通道都准备好,那么 select 语句会随机选择一个通道执行。”

2.测试的代码

为了验证这个随机选择的公平性,我尝试用一个for循环包裹select结构体。通过循环2次的方式验证是否真的时随机的选择准备好的通道。代码如下:

package main
import (
    "fmt"
)
func main() {
    c1 := make(chan string)
    c2 := make(chan string)
    go func() {
        c1 <- "one"
    }()
    go func() {
        c2 <- "two"
    }()

    for i := 0; i < 2; i++ {
        fmt.Println("第")
        fmt.Println(i)
        fmt.Println("次循环")
        select {
        case msg1 := <-c1:
            fmt.Println("received", msg1)
        case msg2 := <-c2:
            fmt.Println("received", msg2)
        }
    }
}

3. 效果预期

根据上面描述的“随机选择”的结论,在执行for循环后,应该会出现4中组合,分别是:
1.1 received one 和 received one
1.2 received two 和 received two
1.3 received one 和 received two
1.4 received two 和 received one

4.实际得到的结果

代码运行的实际结果是,不会出现2次输出一样的内容,始终都是one和two交替出现。
我的疑问在于:既然select选择通道是随机的,那么每次for循环都会是在one和two之间随机选,也就应该有两个one或者两个two的情况发生。
select公平性的疑问

为什么没有出现“输出两个相同结果”的情况呢?

由于我是刚接触go不久,还在基础学习阶段,对这个问题的成因不清除或者说对select和通道的理解不透彻,希望知道原因的前辈答疑解惑,谢谢!

讨论数量: 5
goStruct

因为你用的是无缓冲阻塞通道

1年前 评论
babygo (楼主) 1年前

一次多写几个值进去,在读取试试

1年前 评论
babygo (楼主) 1年前
xiaopi 1年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!