java thread : select poll epoll
Select/Poll函数
Selec()的3种情况:
1. 永远等待下去:直到有一个描述字准备好IO才返回,此时select()函数的参数timeout设置为空指针
2. 等待固定的时间:在不超过等待时间的情况下,有一个描述字准备好IO时才返回. (返回之后,)
3. 不等待:检查描述字之后立即返回,这称为轮询。
Select返回的情况:
集合fd中的任何描述字准备好读
集合fd中的任何描述字准备好写
集合fd中的任何描述字有异常条件待处理
等待了timeout的时间
Select参数会通知内核程序对哪些描述字(fd)感兴趣以及感兴趣的条件(读 写或异常条件)以及等待多长时间 . 描述字不限制于套接字,任何描述字都可用select来测试
(PS: select对所管理的描述字是有MAX限制的)
Select Poll 本质也是阻塞的
摘自:http://kaiyuan.blog.51cto.com/930309/341121
1将用户传入的pollfd数组拷贝到内核空间,因为拷贝操作和数组长度相关,时间上这是一个O(n)操作,这一步的代码在do_sys_poll中包括从函数开始到调用do_poll前的部分。
每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大
2查询每个文件描述符对应设备的状态,如果该设备尚未就绪,则在该设备的等待队列中加入一项并继续查询下一设备的状态。查询完所有设备后如果没有一个设备就绪,这时则需要挂起当前进程等待,直到设备就绪或者超时,挂起操作是通过调用schedule_timeout执行的。
每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大
3设备就绪后进程被通知继续运行,这时再次遍历所有设备,以查找就绪设备。这一步因为两次遍历所有设备,时间复杂度也是O(n),这里面不包括等待时间。相关代码在do_poll函数中。
将获得的数据传送到用户空间并执行释放内存和剥离等待队列等善后工作,向用户空间拷贝数据与剥离等待队列等操作的的时间复杂度同样是O(n),具体代码包括do_sys_poll函数中调用do_poll后到结束的部分。
EPOLL
select和poll都只提供了一个函数——select或者poll函数。
而epoll提供了三个函数,epoll_create,epoll_ctl和epoll_wait,
epoll_create是创建一个epoll句柄;
epoll_ctl是注册要监听的事件类型;
epoll_wait则是等待事件的产生。
先来看sys_epoll_create(epoll_create对应的内核函数),这个函数主要是做一些准备工作,比如创建数据结构,初始化数据并最终返回一个文件描述符(表示新创建的虚拟epoll文件),这个操作可以认为是一个固定时间的操作。
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->
epoll是做为一个虚拟文件系统(虚拟fd Manager)来实现的,这样做至少有以下两个好处:
1,可以在内核里维护一些信息,这些信息在多次epoll_wait间是保持的,比如所有受监控的文件描述符。
2, epoll本身也可以被poll/epoll;
接着是sys_epoll_ctl(epoll_ctl对应的内核函数),需要明确的是每次调用sys_epoll_ctl只处理一个文件描述符,这里主要描述当op(operate)为EPOLL_CTL_ADD时的执行过程,
op:要进行的操作例如注册事件,可能的取值EPOLL_CTL_ADD 注册、EPOLL_CTL_MOD 修 改、EPOLL_CTL_DEL 删除
sys_epoll_ctl做一些安全性检查后进入ep_insert,ep_insert里将 ep_poll_callback做为回掉函数加入设备的等待队列(假定这时设备尚未就绪),由于每次poll_ctl只操作一个文件描述符,因此也可以认为这是一个O(1)操作
ep_poll_callback函数很关键,它在所等待的设备就绪后被系统回掉,执行两个操作:
1,将就绪设备加入就绪队列,这一步避免了像poll那样在设备就绪后再次轮询所有设备找就绪者,降低了时间复杂度,由O(n)到O(1);
2,唤醒虚拟的epoll文件;
epoll的优点:
1、没有最大并发连接的限制,能打开的FD的上限远大于1024(1G的内存上能监听约10万个端口);
2、效率提升,不是轮询的方式,不会随着FD数目的增加效率下降。只有活跃可用的FD才会调用callback函数;
即Epoll最大的优点就在于它只管你“活跃”的连接,而跟连接总数无关,因此在实际的网络环境中,Epoll的效率就会远远高于select和poll。
3、 内存拷贝,利用mmap()文件映射内存加速与内核空间的消息传递;即epoll使用mmap减少复制开销。
上一篇: ThreadLocal 简单分析
下一篇: ThreadLocal 简单分析
推荐阅读
-
Python—IO多路复用之select模块详解(select、poll、epoll之间的区别)
-
IO多路复用(二) -- select、poll、epoll实现TCP反射程序
-
linux epoll,poll,select
-
IO复用之select poll epoll的总结(推荐)
-
java thread : select poll epoll
-
java thread : select poll epoll
-
深度理解select、poll和epoll
-
IO多路复用select/poll/epoll详解以及在Python中的应用
-
7.10 第九章I/O复用高级函数 select poll epoll(lt et)
-
I/O多路转接——select、poll 和 epoll