为什么 Go 语言 select 函数会打乱 Channel 选择顺序?
go 语言 select 函数中打乱选择 channel 顺序
在 go 语言的 select 语句中,你会注意到 channel 被选择的顺序似乎是混乱的。这可能是第一次使用 select 函数的人的一个困惑点,让我们来了解一下为什么会出现这种情况。
防止饥饿问题
select 语句会监听多个 channel 的可读或可写状态,并根据第一个就绪的 channel 执行相应的 case。如果你按顺序选择 channel,可能会导致一种称为“饥饿”的问题。
考虑一个例子,其中 case1 和 case2 同时监听不同的 channel:
for { select { case <-case1: // 执行 case1 case <-case2: // 执行 case2 } }
假设 case1 的 channel 总是在产生数据,而 case2 的 channel 很少产生数据。在这种情况下,case1 将一直先执行,因为它的 channel 上总是有数据。case2 即使有数据,也没有机会执行。
随机选择
为了防止这个问题,go 语言中 select 语句的内部实现会随机打乱 channel 的选择顺序。这样,每个 channel 在多个 channel 同时就绪的情况下都有机会被执行。
通过使用随机选择,select 语句可以确保即使一个 channel 始终就绪,其他 channel 也有机会执行,从而避免饥饿问题。