select多路选择的模拟实现
时间:2022-05-05
本文章向大家介绍select多路选择的模拟实现,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
有时候有这样一种应用场景:需要等待多个事件到达,然后返回尽可能多的事件;如果没有事件到达就阻塞等待。例如服务器等待客户端建立连接,或者等待客户端数据等就有这种应用需求。
在go语言里,可以利用select原语和它的非阻塞(default)分支组合实现这个功能:
// 从ch获取尽可能多的数据放到events里,并返回实际数量;如果没有数据就阻塞等待
func wait(ch chan int, events []int) int {
count := 0
for count < len(events) {
select {
case x := <-ch:
events[count] = x
count++
default:
if count > 0 {
return count
}
events[count] = <-ch
count++
}
}
return count
}
如果再加上退出检查:
import "errors"
func wait(ch chan int, exit chan bool, events []int) (int, error) {
count := 0
for count < len(events) {
select {
case <-exit:
return 0, errors.New("exit")
case x := <-ch:
events[count] = x
count++
default:
if count > 0 {
return count, nil
}
select {
case <-exit:
return 0, errors.New("exit")
case x := <-ch:
events[count] = x
count++
}
}
}
return count, nil
}
可以看到,这里的实现有很多重复代码,非常的冗长难读。我们可以利用channel以下特性改写一下:
1.读取或者写入空channel时永久阻塞
2.读取一个已经关闭的channel立即返回空值
import "errors"
var (
CLOSED = make(chan int)
)
func init() {
close(CLOSED)
}
func pass(flag bool) chan int {
if flag {
return CLOSED
}
return nil
}
func wait(ch chan int, exit chan bool, events []int) (int, error) {
count := 0
LOOP:
for count < len(events) {
select {
case <-exit:
return 0, errors.New("exit")
case x := <-ch:
events[count] = x
count++
case <-pass(count > 0):
break LOOP
}
}
return count, nil
}
现在的实现就比较清晰简洁易读。
- Visual Studio 2015正式发布
- 科技巨头纷纷入局 医疗人工智能需要奋起直追?
- Windows PowerShell 工具
- 游戏开发之在UE4中编写C++代码控制角色
- Visual Studio 64位应用程序编译
- Windows 7 上安装Visual Studio 2015 失败解决方案
- Silverlight调用本机exe程序
- 游戏开发之UE4添加角色到场景中
- 人工智能取代人类?高通副总裁这样说
- Disque:Redis之父新开源的分布式内存作业队列
- mac OS X Yosemite 上编译hadoop 2.6.0/2.7.0及TEZ 0.5.2/0.7.0 注意事项
- EasyStack郭长波连任OpenStack基金会独立董事
- VMware Fusion 中如何复制centos/linux虚拟机
- 浅谈国外航空发动机大数据应用
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 2017 年ICPC 中国大陆区域赛铜牌题解
- 搜索(DFS BFS)专题练习
- AtCoder Beginner Contest 171
- AtCoder Beginner Contest 173 A ~ F(已经补完)
- AtCoder Beginner Contest 174 A ~ E
- AtCoder Beginner Contest 170
- 【队伍训练3】Codeforces Round #661 (Div. 3)
- 购物
- 指纹锁(自定义下比较重载下set的圆括号比较)
- 糖糖别胡说,我真的不是签到题目
- 分数线划定
- 小C的记事本
- 简单的数据结构 (deque的应用)
- [HNOI2003]激光炸弹 (二维前缀和)
- 链表(实现插入一个数)