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典型用法

最新文章

  1. 利用Microsoft.Practices.Unity的拦截技术,实现.NET中的AOP
  2. VFP不同句柄 同一事务处理 统一提交或回滚
  3. AfNetworking 3.0源码解读
  4. HDU5855 Less Time, More profit(最大权闭合子图)
  5. 第六章 - 图像变换 - 图像拉伸、收缩、扭曲、旋转[1] - 仿射变换(cvWarpAffine)
  6. javascript笔记整理(概述,变量,数据类型)
  7. Nagios经check_http监视web申请书server多个tomcat维修
  8. thinkphp中的ajax分页
  9. org.apache.commons.beanutils.BeanMap简单使用例子
  10. Ajax 跨域 异步 CORS
  11. 【Tomcat】Tomcat的使用
  12. OpenCV由汉字生成图片(透明)----可以对抗论文查重!!!
  13. navicat连接IEE数据库查询话单
  14. DJango 前三天小结
  15. Javascript URI 解析介绍
  16. python 基本运算符
  17. CSS之a标签锚点
  18. 简单 babel plugin 开发-使用lerna 工具
  19. excel中如何将时间戳转换为日期格式
  20. Shrio第一天——入门与基本概述

热门文章

  1. 安卓Unity3d游戏的逆向破解
  2. PHP FILTER_VALIDATE_BOOLEAN 过滤器
  3. Eclipse中安装插件的方法
  4. AcWing 196. 质数距离(筛法+离散化)打卡
  5. Wannafly Winter Camp Day8(Div1,onsite) E题 Souls-like Game 线段树 矩阵乘法
  6. Java的poi技术遍历Excel时进行空Cell,空row,判断
  7. Golang(Go语言)内置函数之copy用法
  8. VS2012编译WDM驱动
  9. 使用poi实现生成excel文件
  10. java程序中线程cpu使用率计算