IO多路复用之epoll

IO多路复用之epoll

epoll出现背景

在前面的文章中我们了解了,select的用法,也大体知道IO多路复用的概念。
今天我们就来了解epoll,select是早期的一个用来解决高并发的IO多路复用的手段,最大的缺点就是有文件描述符上限,同时监控的文件描述符不能太多,太多效率会下降,select内部采用了数据的用户态拷贝到内核态,在内核态下进行文件描述符轮询的监控,这样一来就要反复的进行数据的拷贝,所以效率也会降低。

随着互联网的发展,select在高并发显的有些不足,所以就出现了poll,poll解决了select文件描述符上限的问题,但是还是用了在内核态轮询的去监控就绪的文件描述符,效率也是随着监控的增多,效率就会降。相比select在调用接口上进行了优化,把输入的参数和输出参数分开。

最后出现了epoll也是目前比较优的IO多路复用的方式。在接口设计的角度上,epoll将接口分为三个,创建,设置和等待分离。而且后面维护了一些机制来提高效率!下来我就来详细的介绍:

epoll的函数接口

我们从epoll的函数接口说起,epoll首先是需要创建一个句柄,也就是创建出维护高效的三个机制,分别是回调机制,红黑树的事件的设置,就绪队列的时间处理。
epoll的创建。

int epoll_create(int size); // 用于创建一个epoll的句柄。

参数
size现在已经不用了,但是如果要设置,要设置的稍微大点。
返回值
就是一个创建好的epoll句柄,用来操纵epoll的。
epoll的控制

// 用于对事件的添加与删除,事件包括读事件写事件和错误事件
int epoll_ctl(int epfd, int op, int fd, struct epoll_event* event);

参数
epfd 是epoll创建的文件句柄
op是处理事件的动作,比如是添加事件还是删除事件
fd 是要监听的文件描述符
event是一个结构体指针,主要是对事件的操作,比如读事件或者写事件
结构体总体结构:

struct epoll_event
{
uint32_t events;
epoll_data_t data;
}__EPOLL_PACKED;
typedef union epoll_data
{
void * ptr;
int fd;
uint32_t u32;
uint64_t u64;
}epoll_data_t;

epoll的等待

// 是用来进行等待有数据发生的文件描述符
int epoll_wait(int epfd, struct epoll_event* events, int maxevents, int timeout);

参数
epfd 是epoll_create创建的句柄
events 是一个输出型参数,是一个数组
maxevents 数组的大小
timeout 超时时间,如果是-1就表示永久阻塞
返回值
函数调用成功返回就绪事件的个数,如果超时返回小于0

epoll的工作原理

前面我们提到,epoll比select和poll要更加的有优势,因为效率和监控的文件描述符,我们来分析一下工作原理:
在epoll中摒弃了在内核中循环去遍历检测是否有事件的发生,而是采用了回调机制、红黑树的事件控制和就绪队列。

每个epoll对象会创建出来一个eventpoll 的结构体,用于存放epoll_ctl方法的事件
红黑树是用来对事件设置后,插入到红黑树中,时间复杂度为lg(n)
回调机制是当在网络通信中,最先感知到数据的是网卡,所以当数据到达的时候就会返回,因为在设置的时候,每个时间中对应的一个回调的关系,所以就会很准确的返回,然后将返回的事件放到就绪队列中,epoll_wait会检测就绪队列中是否有数据,如果有就立刻去取,所以时间复杂度为O(1),这样一来虽然维护了三个机制,但是大大的提高了效率。解释

epoll的工作方式

在epoll中有两种工作方式,一种是水平触发,一种是边缘触发
首先我们来了解什么是水平触发,水平触发也就LT,这种触发方式是当epoll检测到socket上有数据的时候,不会进行立刻处理,只是进行处理一部分,然后返回,但是数据没有处理完,这个时候当epoll_wait等待的时候就会检测到有数据,就又会进行继续处理,就这样一直到数据处理完毕后采用会到epoll_wait这里进行阻塞等待。

边缘触发是当epoll检测到socket上有事件就绪,就必须处理。但是处理只是处理一次,处理一次后epoll_wait 就不会再返回,ET模式在性能上比LT要好,因为在ET中是立刻读取数据,但是就是一次读取不完,这样就需要搭配循环的去读取数据。读取数据要设置成非阻塞模式。

epoll使用场景

在IO多路复用中,主要是用少量的线程去监视大批的文件描述符,节约资源,但是这样的话都使用于,有万级用户连接,但是只有少量的用户活跃,这样的场景更适用与IO多路复用

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值