I/O多路复用模型实现——epoll

本文涉及的产品
交互式建模 PAI-DSW,5000CU*H 3个月
简介: I/O多路复用模型实现——epoll

I/O多路复用


I/O 多路复用的本质,是通过一种机制(系统内核缓冲I/O数据),让单个进程可以监视多个文件描述符,一旦某个描述符就绪(一般是读就绪或写就绪),能够通知程序进行相应的读写操作。

所谓I/O多路复用指的是这样一个过程:


我们拿到了一堆文件描述符(不管是网络相关的、还是磁盘文件相关等等,任何文件描述符都可以)

通过调用某个函数告诉内核:“这个函数你先不要返回,你替我监视着这些描述符,当这堆文件描述符中有可以进行I/O读写操作的时候你再返回”

当调用的这个函数返回后我们就能知道哪些文件描述符可以进行I/O操作了。

也就是说通过I/O多路复用我们可以同时处理多路I/O。

epoll机制可以用来进行I/O多路复用


epoll 的核心数据结构是:1个红黑树和1个链表。还有3个核心API

8.png

熟悉一下epoll


epoll


epoll_create(int size)


创建一个epoll的句柄,size用来告诉内核这个监听的数目一共有多大


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


第一个参数是epoll_create()的返回值
第二个参数表示动作
  EPOLL_CTL_ADD:注册新的fd到epfd中
  EPOLL_CTL_MOD:修改已经注册的fd的监听事件
  EPOLL_CTL_DEL:从epfd中删除一个fd
第三个参数是需要监听的fd
第四个参数是告诉内核需要监听什么事,在被监测的文件描述符上实际发生的事件。


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


第1个参数 epfd是 epoll的描述符
第2个参数 events则是分配好的 epoll_event结构体数组,epoll将会把发生的事件复制到 events数组中
第3个参数 maxevents表示本次可以返回的最大事件数目,通常 maxevents参数与预分配的events数组的大小是相等的
第4个参数 timeout表示在没有检测到事件发生时最多等待的时间(单位为毫秒),如果 timeout为0,则表示 epoll_wait在 rdllist链表中为空,立刻返回,不会等待;timeout = -1表示调用将一直阻塞,直到有文件描述符进入ready状态或者捕获到信号才返回


epoll event


EPOLLIN:描述符处于可读状态
EPOLLOUT:描述符处于可写状态
EPOLLET:将epoll event通知模式设置成edge triggered
EPOLLONESHOT:第一次进行通知,之后不再监测
EPOLLHUP:本端描述符产生一个挂断事件,默认监测事件
EPOLLRDHUP:对端描述符产生一个挂断事件
EPOLLPRI:由带外数据触发
EPOLLERR:描述符产生错误时触发,默认检测事件


epoll流程

Epoll流程:


当某个进程调用epoll_create方法时,内核会创建一个eventpoll对象(也就是程序中epfd所代表的对象)。eventpoll对象也是文件系统中的一员,和socket一样,它也会有等待队列。

9.png

创建epoll对象后,可以用epoll_ctl添加或删除所要监听的socket。以添加socket为例,如下图,如果通过epoll_ctl添加sock1、sock2和sock3的监视,内核会将eventpoll添加到这三个socket的等待队列中

10.png

当socket收到数据后,中断程序会操作eventpoll对象,而不是直接操作进程。

当socket收到数据后,中断程序会给eventpoll的“就绪列表”添加socket引用。如下图展示的是sock2和sock3收到数据后,中断程序让rdlist引用这两个socket。11.png


eventpoll对象相当于是socket和进程之间的中介,socket的数据接收并不直接影响进程,而是通过改变eventpoll的就绪列表来改变进程状态。

当程序执行到epoll_wait时,如果rdlist已经引用了socket,那么epoll_wait直接返回,如果rdlist为空,阻塞进程。

假设计算机中正在运行进程A和进程B,在某时刻进程A运行到了epoll_wait语句。如下图所示,内核会将进程A放入eventpoll的等待队列中,阻塞进程。

12.png

当socket接收到数据,中断程序一方面修改rdlist,另一方面唤醒eventpoll等待队列中的进程,进程A再次进入运行状态(如下图)。也因为rdlist的存在,进程A可以知道哪些socket发生了变化。

13.png


相关文章
|
4月前
|
负载均衡 NoSQL 网络协议
网络中的阻塞与非阻塞以及reactor模型
网络中的阻塞与非阻塞以及reactor模型
19 0
|
4月前
|
消息中间件 Kubernetes NoSQL
多路复用I/O-epoll
多路复用I/O-epoll
33 0
|
17天前
|
Unix
poll 函数 I/O 多路复用的技术
【4月更文挑战第14天】poll 是另一种在各种 UNIX 系统上被广泛支持的 I/O 多路复用技术,虽然名声没有 select 那么响,能力一点不比 select 差,而且因为可以突破 select 文件描述符的个数限制,在高并发的场景下尤其占优势。
|
4月前
网络编程-epoll模型
网络编程-epoll模型
|
4月前
|
缓存 Linux NoSQL
epoll与reactor浅析
epoll与reactor浅析
|
4月前
epoll分析
epoll分析
|
8月前
|
监控
多路复用
多路复用
43 0
|
9月前
|
存储 Linux
select/poll/epoll
select/poll/epoll
32 0
|
10月前
|
NoSQL Redis
I/O多路复用模型?
I/O多路复用模型?
37 0
|
Linux
linux网络编程(六)epoll反应堆
linux网络编程(六)epoll反应堆
145 1
linux网络编程(六)epoll反应堆