select

2021/07/27 go探索发现 共 642 字,约 2 分钟

云原生科学-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表示从管道读出的数据或者写入管道的数据的存放地址。

文档信息

Search

    Table of Contents