首先我们了解一下什么是I/O复用。I/O就是指网络中的I/O(即输入输出),多路是指多个TCP连接,复用是指一个或少量线程被重复使用。连起来理解就是,用少量的线程来处理网络上大量的TCP连接中的I/O。常见的I/O复用有以下三种:

  1. select
  2. poll
  3. epoll

为什么使用epoll?

这个问题也可以理解为epoll相比于select和poll有什么缺点。首先我们来分析一下select。

select函数声明:

#include<sys/select.h>
#include<sys/time.h>
int select(int maxfdpl,fd_set *readset,fd_set *writeset,fd_set *exceptset,const struct timeval *timeout);

函数第一个参数是被监听的描述符的最大值+1,select底层的数据结构是位数组,因此必须知道被监听的最大描述符才可以确定描述符的范围,否则就需要将整个数组遍历一遍。

函数第二、三、四个参数是被监听的事件,分别是读、写、异常事件。

函数的最后一个参数是监听的时间(NULL、0、正值)

selct缺点:

  1. 可以从函数参数列表上来看,select只能监听读、写、异常这三个事件
  2. selct监听的描述符是有最大值限制的,在Linux内核中是1024
  3. select的实现是每次将待检测的描述符放在位数组中,全部传给内核进行监听,内核监听之后会返回一个就绪描述符个数,并且修改了监听的事件值,以表示该事件就绪。内核再将修改后的数组传给用户空间。用户空间只能通过遍历所有描述符来处理就绪的描述符,之后再将描述符传给内核继续监听......很明显,这样在监听的描述符少的情况下并不影响效率,但是监听的描述符数量特别大的情况下,每次又只有少数描述符上有事件就绪,大量的换入换出会使得效率十分低下

第二步,我们接着分析一下poll

poll函数声明:

int poll(struct pollfd fdarray[],unsigned long nfds,int timeout);
struct pollfd{int fd;short events;short revents;};

第一个参数是个结构体数组,结构体中声明了被监听描述符和相应的事件,每个被监听的描述符对应一个结构体,数组表示可以监听多个描述符。

第二个参数是被监听描述符的个数。

第三个参数同select,只监听时间

poll缺点:

从函数参数来看,poll解决了select前两个问题,监听的描述符数量没有严格限制,监听的事件不止读、写、异常,但是第三个缺点依然存在,存在大量的换入换出。

在Linux2.4及以前的版本中使用的是select和poll,在2.6的时候使用的是epoll,正是因为epoll解决了select和poll共同存在的问题。接下来我们看一下epoll是怎么解决的。

epoll的相关函数

#include <sys/epoll.h> int epoll_create(int size);int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

epoll内核剖析

  • epoll_create

epoll_create的做法是创建出一个内核事件表,实际上就是创建文件,这其中包括文件描述符的分配、文件实体的分配等等,在这里我们记住文件描述符中有一个域很重要,就是:private_data域,该域才是epoll的核心,其中有内核时间表、就绪描述符队列等信息。如下图:

  • epoll_ctl

该函数主要是对内核事件表的操作,涉及插入(添加监听描述符)、删除(删除被监听的描述符)、修改(修改被监听的描述符)。主要有以下步骤:

  1. 遍历内核事件表,看该描述符是否在内核事件表中。
  2. 判断所要做的操作:插入、删除或是修改
  3. 根据操作做相应处理

注意:此处注意的一点是在插入的时候,对相应的描述符注册了回调函数,即当该描述符上有数据就绪时,自动调用回调函数将该描述符加入就绪队列

  • epoll_wait

在看epoll_wait之前,我们来以下内核事件表和组织就绪描述符的数据结构。内核事件表的底层数据结构是红黑树,就绪描述符的底层数据结构是链表。

epoll_wait的功能就是不断查看就绪队列中有没有描述符,如果没有就一直检查、直到超时。如果有就绪描述符,就将就绪描述符通知给用户。此处有关ET和LT模式就是在给用户空间返回就绪描述符的时候体现的。

回顾以下ET模式和LT模式:ET模式是高效模式,就绪描述符只通知用户一次,如果用户没做处理内核将不再进行通知;LT模式比较稳定,如果用户没有处理就绪的描述符,内核会不断通知。

接下来我们看一下具体是怎么实现的。当为ET模式时,上边我们提到就绪描述符是用链表组织的,因此只需将就绪部分断链发给用户,而在LT模式下,用户没有处理就绪描述符时,内核会再次将未处理的就绪描述符加入到就绪队列中重复提醒用户空间。

文末给大家分享c/c++ Linux服务器高阶知识视频资料的朋友可以加群720209036获取

知识点有C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等等。

epoll监听文件_epoll详解——从功能到内核相关推荐

  1. epoll监听文件_epoll使用详解

    epoll介绍 epoll的行为与poll(2)相似,监视多个有IO事件的文件描述符.epoll除了提供select/poll那种IO事件的水平触发(Level Triggered)外,还提供了边缘触 ...

  2. android触摸滑动监听,Android 滑动监听的实例详解

    Android 滑动监听的实例详解 摘要: ScollBy,ScollTo是对内容的移动,view.ScollyBy是对view的内容的移动 view,ScollTo是对内容的移动(移动到指定位置), ...

  3. epoll监听文件_介绍一下 Android Handler 中的 epoll 机制?

    介绍一下 Android Handler 中的 epoll 机制? 目录: IO 多路复用 select.poll.epoll 对比 epoll API epoll 使用示例 Handler 中的 e ...

  4. epoll监听文件_【原创】万字长文浅析:Epoll与Java Nio的那些事儿

    " Epoll 是Linux内核的高性能.可扩展的I/O事件通知机制. 在linux2.5.44首次引入epoll,它设计的目的旨在取代既有的select.poll系统函数,让需要大量操作文 ...

  5. java监听机制_详解java的事件监听机制和观察者设计模式

    首先说说监听器: 监听器就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执 行. java的事件监 ...

  6. epoll监听文件_怎么理解把标准输入以ET模式加入epoll,监听EPOLLOUT事件时,epoll_wait多次返回?...

    确实是后面的printf导致的,去掉后面的printf,增加计数器的判断, 可确认epoll_wait只返回了一次.但是为什么printf会影响到标准输入stdin?还是不理解. 修改后符合预期代码如 ...

  7. Tomcat 的 Server 文件配置详解

    转载自  Tomcat 的 Server 文件配置详解 前言 Tomcat隶属于Apache基金会,是开源的轻量级Web应用服务器,使用非常广泛.server.xml是Tomcat中最重要的配置文件, ...

  8. Java--web.xml加载过程;文件标签详解

    一.web.xml加载过程 我们在启动Javaweb项目时,首先需要启动一个容器(如Tomcat,JBoss) WEB加载web.xml过程如下: 1.在启动Web项目时,容器(如Tomcat,JBo ...

  9. Handler ,MessageQueue 的Looper中epoll监听的fd

    hi,同学们大家好! 这些天有学员再群里问起了Handler中有个数据监听相关问题,学员有的认为Handler数据传递是靠流传递,误认为是epoll中监听的fd进行传递的,这个其实有必要更正这个学员的 ...

最新文章

  1. 设计模式-Observer模式
  2. python快速上手 让繁琐工作自动化 英文版_入门python:《Python编程快速上手让繁琐工作自动化》中英文PDF+代码...
  3. python中math库最大值_python-math库解析
  4. Spring: @Import @ImportResource引入资源
  5. Visual Studio 2010 - 推荐的扩展[关闭]
  6. PageHelpe的分页不起作用
  7. 社交媒体爬虫------调用微博API获取微博内容
  8. 计算机录音机应用程序在哪,Windows录音机在哪 电脑录音机怎么用
  9. DNF脚本完整源码编辑可用
  10. ppt —— 矢量图标库
  11. 计算机配件对比,基本参数 尺寸对比 接口对比
  12. 无法打开计算机的组策略,本地组策略编辑器打不开?Win7本地组策略编辑器无法打开的解决方法...
  13. 2pin接口耳机_耳机插头接线示意图
  14. 单片机入门(预备知识)-适合初学者
  15. Day01 字体样式,变形的旋转 缩放 位移和线性渐变
  16. miniGUI源码分析:消息机制
  17. 熬之滴水穿石:一切从windows编程开始(3)
  18. resources Builders 校验
  19. 扁平化大漠主题卡通 PPT模板
  20. 英雄联盟服务器选择显示符号,lol起名字可以用什么符号 lol名字符号大全

热门文章

  1. 长连接、短连接、短轮询、长轮询
  2. 医学影像阅读/分析软件FSLeyes安装避坑+核磁共振影像数据处理
  3. R构建SVM回归模型
  4. Python代码发现链表中的环并输出环中的第一个元素
  5. 回归模型(regression model)有哪些指标?如何计算回归指标(regression metrics)?如何可视化他们?
  6. java calendar去掉时分秒_java 8:只取年月日的java.util.Date(时分秒清零)对象
  7. ccf z字形 java_第三次CCF计算机软件能力认证题目:Z字形扫描
  8. python pandas dataframe 列 转换为离散值
  9. 【JVM】Java变量的种类(提高版)
  10. 人群分析--ResnetCrowd: A Residual Deep Learning Architecture