博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux -- epoll 事件模型详解
阅读量:5780 次
发布时间:2019-06-18

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

epoll 主要采用对已就绪的 fd 进行轮询操作

一、epoll 触发方式

epoll支持 ET 和 LT 两种触发方式

ET(边缘触发):

Nginx 就是采用 ET 触发方式,只支持 no-block 方式,当一个 fd 缓冲区就绪的时候,只会发送一次事件触发, 而不会管缓冲区的数据是否已经被读取,都不会再发送第二次

LT(边缘触发):

支持no-block 和 block 两种方式,当一个 fd 缓冲区就绪时,只要缓冲区有数据,就会不停的发送就绪通知

 

二、epoll 相关函数:

2.1、int epoll_create(int size);

用于创建一个 epoll 句柄,创建一个 epoll 句柄之后,会占用一个 fd 描述符,对于一个进程来说,它相关的 fd 描述符可以查看/proc/进程id/fd/, 在使用完epoll 之后,需要对他进行 close ,否则会导致 fd 太多被耗尽

 

2.2、int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

事件注册函数,将 fd 添加、修改、删除到 epfd 中,通过 op 参数修改

EPOLL_CTL_ADD:注册新的fd到epfd中;
EPOLL_CTL_MOD:修改已经注册的fd的监听事件;
EPOLL_CTL_DEL:从epfd中删除一个fd;
 

2.3、int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

可以理解为收集epoll 监控的所有事件中,已经发生的那部分 fd 的数量

 

三、epoll 工作原理

3.1、在调用 epoll_create 之后,内核就已经创建了一个 eventpoll 红黑树结构体,一个 list 双向链表,在内核态准备接受存储需要监控的 fd。

3.2、在调用 epoll_ctr 之后,直接向内核态的 eventpoll 进行 add/mod/del 对应的 fd,对于新添加进来的 fd,重复的 fd 可以通过 eventpoll 红黑树识别出来,而不需要再次从用户态拷贝到内核态这个过程
3.3、同时 epoll 还维护了一个双向的 list 链表, 在epoll_ctr执行的时候,除了会向eventpoll 红黑树添加修改外,还会在内核中断函数处理程序中注册一个回调函数,告诉内核,当这个 fd 就绪之后,将他放到 list 里面去。
3.4、在 epoll_wait 调用的时候,就是观察这个双向 list 是否有数据,有就直接处理即可
 

四、伪代码

fd = socket_connect()  #建立一个网络连接efd = epoll_create(0)   #创建一个epollepoll_ctl(efd, EPOLL_CTL_ADD, fd, &event)  #将网络连接 fd 添加到efd中n = epoll_wait(efd, events, MAXEVENTS, -1) #从 list 中获取已经就绪的 fd 的数量for i in range(n):     ev = events[i]   # 从events 内存中获取已经就绪的 fd,执行相关操作     doing(ev)

五、优点

5.1、没有 fd 数量限制,取决于系统内存的大小,一般来说 1GB 就可以有 10W个

5.2、内核和用户控件使用同一块内存,mmap技术,没有用户态和内核态之间的拷贝,提高效率

5.3、无需遍历所有,仅仅只需要遍历已经就绪的 fd 即可

转载于:https://blog.51cto.com/13126942/2045336

你可能感兴趣的文章
多项式前k项和java_多项式朴素贝叶斯softmax改变
查看>>
OracleLinux安装说明
查看>>
使用@media实现IE hack的方法
查看>>
oracle体系结构
查看>>
使用CocoaPods过程中的几个问题
查看>>
机房带宽暴涨问题分析及解决方法
查看>>
XP 安装ORACLE
查看>>
八、 vSphere 6.7 U1(八):分布式交换机配置(vMotion迁移网段)
查看>>
php5编译安装常见错误和解决办法集锦
查看>>
ORACLE配置,修改tnsnames.ora文件实例
查看>>
Workstation服务无法启动导致无法访问文件服务器
查看>>
我的友情链接
查看>>
JS中比较数字大小
查看>>
jQuery插件的开发
查看>>
基础,基础,还是基础之JAVA基础
查看>>
如何成为一个C++高级程序员
查看>>
我的友情链接
查看>>
显式锁(第十三章)
查看>>
看linux书籍做的一些重要笔记(2011.07.03更新)
查看>>
从案例学RxAndroid开发(上)
查看>>