你需要了解Linux编程的epoll.doc
《你需要了解Linux编程的epoll.doc》由会员分享,可在线阅读,更多相关《你需要了解Linux编程的epoll.doc(6页珍藏版)》请在三一文库上搜索。
1、你需要了解Linux编程的epoll现在有这么一个场景:我是一个很忙的大老板,我有100个手机,手机来信息了,我的秘书就会告诉我“老板,你的手机来信息了。”我很生气,我的秘书就是这样子,每次手机来信息就只告诉我来信息了,老板赶紧去看。但是她从来不把话说清楚:到底是哪个手机来信息啊!我可有100个手机啊!于是,我只能一个一个手机去查看,来确定到底是哪几个手机来信息了。这就是IO复用中select模型的缺点!老板心想,要是秘书能把来信息的手机直接拿到我桌子上就好了,那么我的效率肯定大增(这就是epoll模型)。那我们先来总结一下select模型的缺点:单个进程能够监视的文件描述符的数量存在最大限制
2、,通常是1024,当然可以更改数量,但由于select采用轮询的方式扫描文件描述符,文件描述符数量越多,性能越差;(在linux内核头文件中,有这样的定义:#define _FD_SETSIZE 1024)内核 / 用户空间内存拷贝问题,select需要复制大量的句柄数据结构,产生巨大的开销;select返回的是含有整个句柄的数组,应用程序需要遍历整个数组才能发现哪些句柄发生了事件;select的触发方式是水平触发,应用程序如果没有完成对一个已经就绪的文件描述符进行IO操作,那么之后每次select调用还是会将这些文件描述符通知进程。设想一下如下场景:有100万个客户端同时与一个服务器进程保持
3、着TCP连接。而每一时刻,通常只有几百上千个TCP连接是活跃的(事实上大部分场景都是这种情况)。如何实现这样的高并发?粗略计算一下,一个进程最多有1024个文件描述符,那么我们需要开1000个进程来处理100万个客户连接。如果我们使用select模型,这1000个进程里某一段时间内只有数个客户连接需要数据的接收,那么我们就不得不轮询1024个文件描述符以确定究竟是哪个客户有数据可读,想想如果1000个进程都有类似的行为,那系统资源消耗可有多大啊!针对select模型的缺点,epoll模型被提出来了!epoll模型的优点支持一个进程打开大数目的socket描述符IO效率不随FD数目增加而线性下降
4、使用mmap加速内核与用户空间的消息传递epoll的两种工作模式LT(level triggered,水平触发模式)是缺省的工作方式,并且同时支持 block 和 non-block socket。在这种做法中,内核告诉你一个文件描述符是否就绪了,然后你可以对这个就绪的fd进行IO操作。如果你不作任何操作,内核还是会继续通知你的,所以,这种模式编程出错误可能性要小一点。比如内核通知你其中一个fd可以读数据了,你赶紧去读。你还是懒懒散散,不去读这个数据,下一次循环的时候内核发现你还没读刚才的数据,就又通知你赶紧把刚才的数据读了。这种机制可以比较好的保证每个数据用户都处理掉了。ET(edge-tr
5、iggered,边缘触发模式)是高速工作方式,只支持no-block socket。在这种模式下,当描述符从未就绪变为就绪时,内核通过epoll告诉你。然后它会假设你知道文件描述符已经就绪,并且不会再为那个文件描述符发送更多的就绪通知,等到下次有新的数据进来的时候才会再次出发就绪事件。简而言之,就是内核通知过的事情不会再说第二遍,数据错过没读,你自己负责。这种机制确实速度提高了,但是风险相伴而行。epoll模型API#include /* 创建一个epoll的句柄,size用来告诉内核需要监听的数目一共有多大。当创建好epoll句柄后,它就是会占用一个fd值,所以在使用完epoll后,必须调用
6、close()关闭,否则可能导致fd被耗尽。*/int epoll_create(int size); /*epoll的事件注册函数*/int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); /*等待事件的到来,如果检测到事件,就将所有就绪的事件从内核事件表中复制到它的第二个参数events指向的数组*/int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);epoll的事件注册函数epoll_ctl,第一个参
7、数是 epoll_create() 的返回值,第二个参数表示动作,使用如下三个宏来表示:POLL_CTL_ADD /注册新的fd到epfd中;EPOLL_CTL_MOD /修改已经注册的fd的监听事件;EPOLL_CTL_DEL /从epfd中删除一个fd;struct epoll_event 结构如下:typedef union epoll_data void *ptr; int fd; _uint32_t u32; _uint64_t u64; epoll_data_t;struct epoll_event _uint32_t events; /* Epoll events */ epol
8、l_data_t data; /* User data variable */;epoll_event结构体中的events 可以是以下几个宏的集合:EPOLLIN /表示对应的文件描述符可以读(包括对端SOCKET正常关闭);EPOLLOUT /表示对应的文件描述符可以写;EPOLLPRI /表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来);EPOLLERR /表示对应的文件描述符发生错误;EPOLLHUP /表示对应的文件描述符被挂断;EPOLLET /将EPOLL设为边缘触发(Edge Triggered)模式,这是相对于水平触发(Level Triggered)来说的
9、。EPOLLONESHOT/只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个socket的话,需要再次把这个socket加入到EPOLL队列里。epoll的一个简单使用范例#include #include #include #include #include #include #include #include #include #include #define MAXLINE 5#define OPEN_MAX 100#define LISTENQ 20#define SERV_PORT 5000#define INFTIM 1000void setnonblocking(in
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 需要 了解 Linux 编程 epoll
链接地址:https://www.31doc.com/p-3381849.html