golang的select典型用法

转载 2018年04月17日 15:19:51

golang 的 select 的功能和 select, poll, epoll 相似,就是监听 IO 操作,当 IO 操作发生时,触发相应的动作。

示例:

ch1 := make (chan int, 1)
ch2 := make (chan int, 1)

...

select {
case <-ch1:
    fmt.Println("ch1 pop one element")
case <-ch2:
    fmt.Println("ch2 pop one element")
}

注意到 select 的代码形式和 switch 非常相似,不过 select 的 case 里的操作语句只能是【IO 操作】 。

此示例里面 select 会一直等待等到某个 case 语句完成,也就是等到成功从 ch1 或者 ch2 中读到数据。则 select 语句结束。

【使用 select 实现 timeout 机制】

如下:

timeout := make (chan bool, 1)
go func() {
    time.Sleep(1e9) // sleep one second
    timeout <- true
}()
ch := make (chan int)
select {
case <- ch:
case <- timeout:
    fmt.Println("timeout!")
}

当超时时间到的时候,case2 会操作成功。所以 select 语句则会退出。而不是一直阻塞在 ch 的读取操作上。从而实现了对 ch 读取操作的超时设置。

下面这个更有意思一点。

当 select 语句带有 default 的时候:

ch1 := make (chan int, 1)
ch2 := make (chan int, 1)

select {
case <-ch1:
    fmt.Println("ch1 pop one element")
case <-ch2:
    fmt.Println("ch2 pop one element")
default:
    fmt.Println("default")
}

此时因为 ch1 和 ch2 都为空,所以 case1 和 case2 都不会读取成功。则 select 执行 default 语句。

就是因为这个 default 特性,我们可以使用 select 语句来检测 chan 是否已经满了。

如下:

ch := make (chan int, 1)
ch <- 1
select {
case ch <- 2:
default:
    fmt.Println("channel is full !")
}

因为 ch 插入 1 的时候已经满了,当 ch 要插入 2 的时候,发现 ch 已经满了(case1 阻塞住),则 select 执行 default 语句。这样就可以实现对 channel 是否已满的检测,而不是一直等待。

比如我们有一个服务,当请求进来的时候我们会生成一个 job 扔进 channel,由其他协程从 channel 中获取 job 去执行。但是我们希望当 channel 瞒了的时候,将该 job 抛弃并回复 【服务繁忙,请稍微再试。】就可以用 select 实现该需求。

关于垃圾回收

c++ 写久了的人,刚接触 golang 的时候最不能理解的就是为什么作者要支持垃圾回收。不管是从垃圾回收器的实现上看,还是对于程序员编程习惯的养成方面,都避免不了编写出的程序性能损失。但是写了几天 golang 之后,又觉得有垃圾回收确实大大减轻程序员的心智负担,降低编程门槛,提高编程效率。让我联想到 汇编 和 C语言 的关系,即使 C语言的性能不如汇编写出来的高,但是后者还是颠覆了前者。

Golang select的使用及典型用法

Golang select的使用及典型用法基本使用 select是Go中的一个控制结构,类似于switch语句,用于处理异步IO操作。select会监听case语句中channel的读写操作,当cas...
  • zhaominpro
  • zhaominpro
  • 2017-08-25 11:57:15
  • 440

【golang】Go语言学习-select用法

golang 的 select 的功能和 select, poll, epoll 相似, 就是监听 IO 操作,当 IO 操作发生时,触发相应的动作。 示例: ch1 := make (chan ...
  • zhonglinzhang
  • zhonglinzhang
  • 2015-05-22 09:47:12
  • 16242

GO select用法详解

golang 的 select 就是监听 IO 操作,当 IO 操作发生时,触发相应的动作。  在执行select语句的时候,运行时系统会自上而下地判断每个case中的发送或接收操作是否可以被立即执行...
  • wo198711203217
  • wo198711203217
  • 2017-03-23 15:40:55
  • 8032

Go语言技巧:使用select{}阻塞main函数

很多时候我们需要让main函数不退出,让它在后台一直执行,例如:func main() { for i := 0; i < 20; i++ { //启动20个协程处理消息队列中的消息 ...
  • QQ245671051
  • QQ245671051
  • 2017-02-23 22:59:42
  • 2951

[Golang]Select多路选择的模拟实现

有时候有这样一种应用场景:需要等待多个事件到达,然后返回尽可能多的事件;如果没有事件到达就阻塞等待。例如服务器等待客户端建立连接,或者等待客户端数据等就有这种应用需求。 在go语言里,可以利用se...
  • abv123456789
  • abv123456789
  • 2015-03-11 10:38:27
  • 2494

golang select

golang的select与channel配合使用。它用于等待一个或者多个channel的输出。 应用场景:主goroutine等待子goroutine完成,但是子goroutine无限运行,导致主...
  • kelindame
  • kelindame
  • 2016-05-27 11:30:49
  • 725

Golang的select/非缓冲的Channel实例详解

select golang 的 select 就是监听 IO 操作,当 IO 操作发生时,触发相应的动作。 在执行select语句的时候,运行时系统会自上而下地判断每个case中的发送或接...
  • grassroots2011
  • grassroots2011
  • 2015-10-30 21:19:43
  • 7791

跟着猫哥学Golang 18 - select控制并发

 猫哥在实际项目中,会遇到在一个goroutine中处理多个channel的情况。 一般情况下,可以用select关键字来控制channel。golang中select可以等待/处理多个cha...
  • 972301
  • 972301
  • 2016-10-05 13:20:07
  • 849

golang select 选择器的两种方案

golang select 选择器 常规模式:
  • eclipser1987
  • eclipser1987
  • 2014-05-17 11:37:50
  • 10672

SELECT 的另类用法

  • 2010年01月19日 18:11
  • 499B
  • 下载
收藏助手
不良信息举报
您举报文章:golang的select典型用法
举报原因:
原因补充:

(最多只允许输入30个字)