云原生科学-Go探索发现: select剖析
select
select提供了IO多路复用机制,用于检测多个管道是否就绪(即可读可写)。
特性
- select每个case语句只能操作一个管道,要么写入或者读取数据。如果多个case语句都可读或者可写,则随机挑选一个case执行。
- 当select中存在case是default,就会进行非阻塞操作,否则会阻塞于case<-channel的语句。
- select语句中通常会包含default语句,防止陷入阻塞。空的select语句
select{}
会永远阻塞。
阻塞应用实例
kubernetes的apiserver中webhook测试组件:
func main(){
server:=webhooktesting.NewTestServer(nil)
server.StartTLS()
select {}
}
协程main将陷入永久性阻塞。
实现原理
case数据结构
type scase struct {
c *hchan //操作管道
kind uint16 //case类型
elem unsafe.Pointer // data elemen
}
kind表示case的类型
const(
caseNil =iota //管道值nil
caseRecv // 读管道的case
caseSend
caseDefault
)
由于nil管道不可读写,意味着这类case永远不会命中,在运行时忽略,所以case中向nil管道写数据不会触发panic.
elem数据
elem表示从管道读出的数据或者写入管道的数据的存放地址。
文档信息
- 本文作者:Beast
- 本文链接:https://beastpu.github.io/2021/07/27/go-03/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)