IO多路转接之epoll

github:epoll代码

一、epoll

1.认识epoll
它是Linux内核为处理大批量句柄而做了改进的poll,Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。

2.epoll支持最大fd
它所支持的FD上限是最大可以打开文件的数目,这个数字一般远大于2048,举个例子,在1GB内存的机器上大约是10万左右,具体数目可以cat /proc/sys/fs/file-max查看,一般来说这个数目和系统内存关系很大。

3.select与poll的缺点
select/poll每次调用都会扫描全部集合,导致效率呈线性下降。但是epoll不存在这个问题,它只会对“活跃”的socket进行操作—epoll实现了一个“伪”AIO,因为这时候推动力在os内核。

4.使用mmap加速内核与用户空间的消息传递
无论是select,poll还是epoll都需要内核把FD消息通知给用户空间,如何避免不必要的内存拷贝就很重要,在这点上,epoll是通过内核与用户空间mmap同一块内存实现的。手工进行mmap。

5.工作方式
1)水平触发LT
它是默认的工作模式,支持阻塞和非阻塞读写。内核告诉你一个fd是否就绪了,然后你可以对这个就绪的fd进行IO操作。如果你不作任何操作,内核还是会继续通知你。

2)边缘触发ET
它是高速工作方式,只支持非阻塞的读写,当fd从未就绪变为就绪时,内核通过epoll告诉你。然后它会假设你知道fd已经就绪,并且不再为那个fd发送更多的就绪通知

二、epoll的工作原理

这里写图片描述
当你调用epoll_create创建一个epoll句柄时,内核就开始准备存储要监控的句柄了,当你调用epoll_ctl,就往内核的数据结构里塞入新的socket句柄,这些socket句柄以红黑树的形式保存在内核缓存里,已支持快速的查找、插入、删除。此时还会给内核中断处理程序注册是个回调函数(回调机制),告诉内核,如果这个句柄的中断到了,就将它添加到就绪队列里。所以当一个socket上有数据的时候,内核在把网卡上的数据拷贝到内核中,再将socket插入到就绪队列里。

所以通过一颗红黑树、一个回调机制、一个就绪队列,就可以解决高并发的处理。使用epoll_create创建红黑树和就绪队列,当增加socket时,先检查红黑树中是否有该socket句柄,存在则立即返回,不存在则添加到红黑树中,一旦某个socket句柄发生,就通过回调函数,将此socket句柄添加到就绪队列里,然后只需要调用epoll_wait,就可以立刻返回就绪队列里的数据。

所以说相当于将任务交给了内核,用户只需要拿已发生的socket数据,大大加快了IO效率。

三、相关系统调用

1.epoll_create

int epoll_create(int size);
//创建一个epoll的句柄,从Linux2.6.8之后,size参数可以省略,但还是加上好,可以
//和旧设备兼容,用完之后必须调用close()关闭。

2.epoll_ctl

int epoll_ctl(int epfd,int op,int fd,struct epoll_event *event);
//注册要监听的事件类型,可以操作上面已创建的epoll句柄
//epfd:epoll的句柄
//op:表示动作,用三个宏来表示,可以进行注册、修改、删除
//fd:需要监听的fd
//event:告诉内核需要监听什么事

3.epoll_wait

int epoll_wait(int epfd,struct epoll_event *events,int maxevents,\
int timeout)
//收集在epoll监控的事件中已经发送的事件
//events:是一个结构体数组,将已发生的事件添加到数组中
//maxevents:告诉内核这个events有多大
//timeout:超时时间,0会立即返回,-1是永久阻塞
//函数调用成功,返回对应IO上已经准备好的文件描述符数目。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值