分享
Golang利用select实现goroutine的超时控制
rfyiamcool · · 8893 次点击 · · 开始浏览这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。
简单的说下select是干什么的?
select用来让我们的程序监视多个文件句柄(file descriptor)的状态变化的处理机制。当你发起一些阻塞的请求后,你可以使用select机制轮训扫描fd,直到被监视的文件句柄有某一个或多个发生了状态改变。
该文章写的有些乱,欢迎来喷 ! 另外文章后续不断更新中,请到原文地址查看更新。
本来只是想说下select,但又忍不住废话下说下epoll的处理流程:
我们可以把要监控读写的文件交给内核(epoll_add),而内核通过中断的方式得知事件通知. 这要比select好不少.
设置你关心的事件(epoll_ctl),比如读事件.
然后等(epoll_wait),此时,如果没有哪个文件有你关心的事件,则休眠,直到有事件,被唤醒,然后返回那些事件.
Epoll的优势在于,由接收数据的OS来负责通知你有数据可以操作,因为OS是知道什么时候有数据的。
select 跟golang有啥关联? 首先我们通过上面的介绍得知,select是通过线性扫描的方式监视文件描述符是否有变动. channnel在系统层面来说也是个文件描述符。 在golang里我们可以使用goroutine并发执行任务,接着使用select来监视每个任务的channel情况.
但如果这几个任务都长时间没有回复channel信息,如果我们又有超时timeout需求,那么我们可以使用起一个goroutine,这个goroutine任务逻辑启动sleep,等sleep之后回复channel信号。
说了这么多没用的,才聊到咱们golang goroutine select正事....
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#http://xiaorui.cc
package main
import(
"fmt"
"time"
)
func main(){
timeout:=make(chan bool,1)
go func(){
time.Sleep(3*time.Second)//sleep3second
timeout<-true
}()
ch:=make(chan int)
select{
case<-ch:
case<-timeout:
fmt.Println("task is timeout!")
}
}
上面golang那段代码运行后的结果是:
Python
1
2
task istimeout!
有疑问加站长微信联系(非本文作者)
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
关注微信8893 次点击
添加一条新回复
(您需要 后才能回复 没有账号 ?)
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码` - 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传
收入到我管理的专栏 新建专栏
简单的说下select是干什么的?
select用来让我们的程序监视多个文件句柄(file descriptor)的状态变化的处理机制。当你发起一些阻塞的请求后,你可以使用select机制轮训扫描fd,直到被监视的文件句柄有某一个或多个发生了状态改变。
该文章写的有些乱,欢迎来喷 ! 另外文章后续不断更新中,请到原文地址查看更新。
本来只是想说下select,但又忍不住废话下说下epoll的处理流程:
我们可以把要监控读写的文件交给内核(epoll_add),而内核通过中断的方式得知事件通知. 这要比select好不少.
设置你关心的事件(epoll_ctl),比如读事件.
然后等(epoll_wait),此时,如果没有哪个文件有你关心的事件,则休眠,直到有事件,被唤醒,然后返回那些事件.
Epoll的优势在于,由接收数据的OS来负责通知你有数据可以操作,因为OS是知道什么时候有数据的。
select 跟golang有啥关联? 首先我们通过上面的介绍得知,select是通过线性扫描的方式监视文件描述符是否有变动. channnel在系统层面来说也是个文件描述符。 在golang里我们可以使用goroutine并发执行任务,接着使用select来监视每个任务的channel情况.
但如果这几个任务都长时间没有回复channel信息,如果我们又有超时timeout需求,那么我们可以使用起一个goroutine,这个goroutine任务逻辑启动sleep,等sleep之后回复channel信号。
说了这么多没用的,才聊到咱们golang goroutine select正事....
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#http://xiaorui.cc
package main
import(
"fmt"
"time"
)
func main(){
timeout:=make(chan bool,1)
go func(){
time.Sleep(3*time.Second)//sleep3second
timeout<-true
}()
ch:=make(chan int)
select{
case<-ch:
case<-timeout:
fmt.Println("task is timeout!")
}
}
上面golang那段代码运行后的结果是:
Python
1
2
task istimeout!