epoll提供的接口
epoll提供了3个系统调用
- epoll_create;创建一个epoll
- epoll_ctl:将文件句柄添加到epol中,并注册相关事件到文件句柄
- epoll_wait:返回活跃文件句柄
实现机制
主要数据结构
- 句柄树:为方便查找,epoll使用二叉树存储所有句柄;
- 句柄数组:epoll在用户空间创建句柄数组,用来存放当前活跃句柄。
流程
- 当句柄状态发生变化时会主动将句柄添加到用户空间的句柄数组中;
- 当调用epoll_wait时,epoll返回句柄数组的内存地址,用户通过内存地址就可以获取当前活跃的句柄信息。
ET与LT模式
ET:边缘触发、LT:水平触发
最初epoll只提供了ET模式,因为ET模式对于用户来说难以操作,才妥协推出了性能稍低LT模式,那就看一下两者的区别;
区别
ET模式下,只有某个描述符的状态变为可用后(不可读变为可读/不可写变为可写),调用epoll_wait才会返回该描述符。LT模式下,只要当某个描述符处于某种状态时(可读/可写),每次调用epoll_wait都会返回该描述符;
当用户使用ET模式时,需要在两次epoll_wait调用之间将活跃的描述符一次性将数据读完,或者一次性将数据发完/填满,或者需要在用户代码中保存句柄状态。
性能对比
从性能因素考虑,ET模式效率会高一些,因为活跃的描述符会存放在数组当中,LT模式下每当用户IO操作完成之后,要检查描述符的状态来确定是否删除数组中的描述符;而ET模式只要用户epoll_wait之后,扫过数组就会删除描述符;