Linux平台下优于select的epoll

基于select的I/O复用技术速度慢的原因

  1. 调用select函数后常见的针对所有文件描述符的循环语句
  2. 每次调用select函数时都需要向该函数传递监视对象信息

调用select函数后,并不是把发生变化的文件描述符单独集中到一起,而是通过观察作为监视对象的fd_set变量的变化,找出发生变化的文件描述符,因此无法避免针对所有监视对象的循环语句。而且,作为监视对象的fd_set变量会发生变化,所以调用select函数前应复制并保存原有信息,并在每次调用select函数时传递新的监视对象信息(每次调用select函数时向操作系统传递监视对象信息)。

select函数与文件描述符有关,更准确地说,是监视套接字变化的函数,而套接字是由操作系统管理的,所以select函数绝对需要借助于操作系统才能完成功能。

select的优点

select的兼容性比较高,可以支持很多的操作系统,不受平台的限制,使用select函数满足以下两个条件:

  • 服务器接入者少
  • 程序应该具有兼容性

epoll函数的优点

  1. 无需编写以监视状态变化为目的的针对所有文件描述符的循环语句
  2. 调用对应于select函数的epoll_wait函数时无需每次传递监视对象信息

select方式和epoll方式差异

最大差异在于监视对象文件描述符传递给操作系统的方式。select函数每次调用都要传递所有的监视对象信息,而epoll函数仅向操作系统传递1次监视对象,监视范围或内容发生变化时只通知发生变化的事项。

epoll相关函数

  • epoll_create:创建保存epoll文件描述符的空间(向操作系统请求创建用于保存监视对象文件描述符的空间)
  • epoll_ctl:向空间注册并销毁文件描述符(替代select方式中添加和删除监视对象文件描述符的FD_SET、FD_CLR函数)
  • epoll_wait:与select函数类似,等待文件描述符发生变化(通过epoll_event结构体数组将发生变化的(发生事件的)文件描述符单独集中到一起,而无需针对所有文件描述符进行循环)

epoll_create

#include <sys/epoll.h>

int epoll_create(int size)// 成功时返回epoll文件描述符,失败时返回-1
// size传递创建文件描述符保存空间即epoll例程的大小, 仅供操作系统参考

epoll_ctl

生成epoll例程后,应在其内部注册监视对象文件描述符。

#include <sys/epoll.h>
int epoll_ctl(int epfd, int op, int fd, stuct epoll_event* event);// 成功时返回0,失败时返回-1
// epfd  用于注册监视对象的epoll例程的文件描述符
// op    用于指定监视对象的添加、删除或更改等操作
// fd    需要注册的监视对象文件描述符
// event 监视对象的事件类型

其中epoll_ctl第二个参数传递的常量及含义如下:

EPOLL_CTL_ADD:将文件描述符注册到epoll例程
EPOLL_CTL_DEL:从epoll例程中删除文件描述符
EPOLL_CTL_MOD:更改注册的文件描述符的关注事件发生情况

epoll_ctl第四个参数epoll_event的成员events中可以保存的常量及所指的事件类型如下:

EPOLLIN:需要读取数据的情况
EPOLLOUT:输出缓冲为空,可以立即发送数据的情况
EPOLLPRI:收到OOB数据的情况
EPOLLPDHUP:断开连接或半关闭的情况,这在边缘触发方式下非常有用
EPOLLERR:发生错误的情况
EPOLLET:以边缘触发的方式得到事件通知
EPOLLONESHOT:发生一次事件后,相应文件描述符不再收到事件通知。因此需要向epoll_ctl函数的第二个参数传递EPOLL_CTL_MOD,再次设置事件。

epoll_wait

#include<sys/epoll.h>
int epoll_wait(int epfd, struct epoll_event* events, int maxevent, int timeout);// 成功时返回事件的文件描述符数,失败时返回-1
// epfd   表示事件发生监视范围的epoll例程的文件描述符
// events 保存发生事件的文件描述符集合的结构体地址值
// maxevents 第二个参数可以保存的最大事件数
// timeout 以1/1000秒为单位的等待时间,传递-1时,一直等待直到发生事件

条件触发和边缘触发

条件触发方式中,只要输入缓冲有数据就会一直通知该事件。
边缘触发方式中,输入缓冲收到数据时仅注册1此该事件,即使输入缓冲中还留有数据,也不会再进行注册。

epoll默认以条件触发方式工作,select以条件触发方式工作。如需改成边缘触发,则将epoll_ctl第四个参数epoll_event的成员events改成EPOLLIN|EPOLLET即可。

边缘触发的优点

边缘触发的优点:可以分离接收数据和处理数据的时间点,给服务端的实现带来很大灵活性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
最近在开发im服务器 需要大并发链接 QT默认的是使用select模型的 这种轮询方式非常慢 在高并发连接 我们需要epoll才能发挥linux服务器的性能 而且使用简单 整个服务端代码架构无需修改 直接可以使用 只要在 main文件添加: int main int argc char argv[] { #ifdef Q OS LINUX QCoreApplication::setEventDispatcher new EventDispatcherLibEvent ; qInstallMessageHandler customMessageHandler ; #endif QCoreApplication a argc argv ; auto ser new ConfigServer; ser >startServer ; return a exec ; } 在 pro文件添加 linux{ LIBS + levent core SOURCES + common eventdispatcher libevent eventdispatcher libevent cpp common eventdispatcher libevent eventdispatcher libevent config cpp common eventdispatcher libevent eventdispatcher libevent p cpp common eventdispatcher libevent socknot p cpp common eventdispatcher libevent tco eventfd cpp common eventdispatcher libevent tco pipe cpp common eventdispatcher libevent tco cpp common eventdispatcher libevent timers p cpp HEADERS + common eventdispatcher libevent common h common eventdispatcher libevent eventdispatcher libevent h common eventdispatcher libevent eventdispatcher libevent config h common eventdispatcher libevent eventdispatcher libevent config p h common eventdispatcher libevent eventdispatcher libevent p h common eventdispatcher libevent libevent2 emul h common eventdispatcher libevent qt4compat h common eventdispatcher libevent tco h common eventdispatcher libevent wsainit h } 可以直接跨平台了使用了 csdn博客:http: blog csdn net rushroom">最近在开发im服务器 需要大并发链接 QT默认的是使用select模型的 这种轮询方式非常慢 在高并发连接 我们需要epoll才能发挥linux服务器的性能 而且使用简单 整个服务端代码架构无需修改 直接可以使用 只要在 main文件添加: [更多]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值