关于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的情况发生。
为什么没有出现“输出两个相同结果”的情况呢?
由于我是刚接触go不久,还在基础学习阶段,对这个问题的成因不清除或者说对select和通道的理解不透彻,希望知道原因的前辈答疑解惑,谢谢!
因为你用的是无缓冲阻塞通道
一次多写几个值进去,在读取试试