博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
epoll实现机制分析
阅读量:6072 次
发布时间:2019-06-20

本文共 1352 字,大约阅读时间需要 4 分钟。

 本文只介绍epoll的主要流程而不是分析源代码,如果需要了解更多的细节可以自己翻阅相关的内核源代码.

相关内核代码:
fs/eventpoll.c
判断一个tcp套接字上是否有激活事件:net/ipv4/tcp.c:tcp_poll函数
每个epollfd在内核中有一个对应的eventpoll结构对象.其中关键的成员是一个readylist(eventpoll:rdllist)

和一棵红黑树(eventpoll:rbr).

一个fd被添加到epoll中之后(EPOLL_ADD),内核会为它生成一个对应的epitem结构对象.epitem被添加到

eventpoll的红黑树中.红黑树的作用是使用者调用EPOLL_MOD的时候可以快速找到fd对应的epitem。

调用epoll_wait的时候,将readylist中的epitem出列,将触发的事件拷贝到用户空间.之后判断epitem是否需

要重新添加回readylist.

epitem重新添加到readylist必须满足下列条件:
1) epitem上有用户关注的事件触发.
2) epitem被设置为水平触发模式(如果一个epitem被设置为边界触发则这个epitem不会被重新添加到readylist

中,在什么时候重新添加到readylist请继续往下看).

注意,如果epitem被设置为EPOLLONESHOT模式,则当这个epitem上的事件拷贝到用户空间之后,会将

这个epitem上的关注事件清空(只是关注事件被清空,并没有从epoll中删除,要删除必须对那个描述符调用

EPOLL_DEL),也就是说即使这个epitem上有触发事件,但是因为没有用户关注的事件所以不会被重新添加到

readylist中.

epitem被添加到readylist中的各种情况(当一个epitem被添加到readylist如果有线程阻塞在epoll_wait中,那

个线程会被唤醒):

1)对一个fd调用EPOLL_ADD,如果这个fd上有用户关注的激活事件,则这个fd会被添加到readylist.
2)对一个fd调用EPOLL_MOD改变关注的事件,如果新增加了一个关注事件且对应的fd上有相应的事件激活,

则这个fd会被添加到readylist.

3)当一个fd上有事件触发时(例如一个socket上有外来的数据)会调用ep_poll_callback(见eventpoll::ep_ptable_queue_proc),

如果触发的事件是用户关注的事件,则这个fd会被添加到readylist中.

了解了epoll的执行过程之后,可以回答一个在使用边界触发时常见的疑问.在一个fd被设置为边界触发的情况下,

调用read/write,如何正确的判断那个fd已经没有数据可读/不再可写.epoll文档中的建议是直到触发EAGAIN

错误.而实际上只要你请求字节数小于read/write的返回值就可以确定那个fd上已经没有数据可读/不再可写.

最后用一个epollfd监听另一个epollfd也是合法的,epoll通过调用eventpoll::ep_eventpoll_poll来判断一个

epollfd上是否有触发的事件(只能是读事件).

转载地址:http://ucngx.baihongyu.com/

你可能感兴趣的文章
对象的创建与销毁
查看>>
case功能菜单选项
查看>>
HP ILO2 使用详细教程
查看>>
Scout YYF I (概率+矩阵快速幂)
查看>>
Reverse and Compare(DP)
查看>>
1503 猪和回文(DP)
查看>>
345. 反转字符串中的元音字母
查看>>
在浏览器输入URL后发生了什么?
查看>>
高德地图定位之浏览器定位
查看>>
[ HNOI 2005 ] 狡猾的商人
查看>>
神经网络建模的一些感悟;
查看>>
FTPS (FTP over SSL) vs. SFTP (SSH 文件传输协议): 我们如何做出选择
查看>>
steam账号分享工具、迅游账号分享工具说明:
查看>>
c++中冒号(:)和双冒号(::)的用法
查看>>
ServletContext保存访问量
查看>>
IMSI,TMSI的关系
查看>>
JPA + Hibernate + PostgreSQL + Maven基本配置示例
查看>>
vue cordova生成app
查看>>
Kubernetes安装部署演示介绍
查看>>
koa中间件
查看>>