Linux高并发机制——epoll模型
2015-08-08 16:46
435 查看
epoll是一个特别重要的概念,常常用于处理服务端的并发问题。当服务端的在线人数越来越多,会导致系统资源吃紧,I/O效率越来越慢,这时候就应该考虑epoll了。epoll是Linux内核为处理大批句柄而作改进的poll,是Linux特有的I/O函数。其特点如下:
1.epoll是Linux下多路复用IO接口select/poll的增强版本。其实现和使用方式与select/poll有很多不同,epoll通过一组函数来完成有关任务,而不是一个函数。
2.epoll之所以高效,是因为epoll将用户关心的文件描述符放到内核里的一个事件表中,而不是像select/poll每次调用都需要重复传入文件描述符集或事件集。比如当一个事件发生(比如说读事件),epoll无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入就绪队列的描述符集合就行了。
3.epoll有两种工作方式,LT(level triggered):水平触发和ET(edge-triggered):边沿触发。LT是select/poll使用的触发方式,比较低效;而ET是epoll的高速工作方式。
通俗理解就是,比如说有一堆女孩,有的很漂亮,有的很凤姐。现在你想找漂亮的女孩聊天,LT就是你需要把这一堆女孩全都看一遍,才可以找到其中的漂亮的(就绪事件);而ET是你的小弟(内核)将N个漂亮的女孩编号告诉你,你直接去看就好,所以epoll很高效。另外,还记得我的上一篇文章中小明找女神聊天的例子吗?采用非阻塞方式,小明还需要每隔十分钟回来看一下(select);如果小明有小弟(内核)帮他守在大门口,女神回来了,小弟会主动打电话,告诉小明女神回来了,快来处理吧!这就是epoll。
epoll共有三个函数,如下:
因此,服务端epoll的时候,步骤如下:
1.调用epoll_create函数在Linux内核中创建一个事件表;
2.然后将文件描述符(监听套接字)添加到所创建的事件表中;
3.在主循环中,调用epoll_wait等待返回就绪的文件描述符集合;
4.分别处理就绪的事件集合
下面介绍下如何将一个socket添加到内核事件表中,如下:
1.epoll是Linux下多路复用IO接口select/poll的增强版本。其实现和使用方式与select/poll有很多不同,epoll通过一组函数来完成有关任务,而不是一个函数。
2.epoll之所以高效,是因为epoll将用户关心的文件描述符放到内核里的一个事件表中,而不是像select/poll每次调用都需要重复传入文件描述符集或事件集。比如当一个事件发生(比如说读事件),epoll无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入就绪队列的描述符集合就行了。
3.epoll有两种工作方式,LT(level triggered):水平触发和ET(edge-triggered):边沿触发。LT是select/poll使用的触发方式,比较低效;而ET是epoll的高速工作方式。
通俗理解就是,比如说有一堆女孩,有的很漂亮,有的很凤姐。现在你想找漂亮的女孩聊天,LT就是你需要把这一堆女孩全都看一遍,才可以找到其中的漂亮的(就绪事件);而ET是你的小弟(内核)将N个漂亮的女孩编号告诉你,你直接去看就好,所以epoll很高效。另外,还记得我的上一篇文章中小明找女神聊天的例子吗?采用非阻塞方式,小明还需要每隔十分钟回来看一下(select);如果小明有小弟(内核)帮他守在大门口,女神回来了,小弟会主动打电话,告诉小明女神回来了,快来处理吧!这就是epoll。
epoll共有三个函数,如下:
1、int epoll_create(int size) // 创建一个epoll句柄,参数size用来告诉内核监听的数目,size为epoll所支持的最大句柄数
2、int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) /*函数功能: epoll事件注册函数 参数epfd为epoll的句柄,即epoll_create返回值 参数op表示动作,用3个宏来表示: EPOLL_CTL_ADD(注册新的fd到epfd), EPOLL_CTL_MOD(修改已经注册的fd的监听事件), EPOLL_CTL_DEL(从epfd删除一个fd); 其中参数fd为需要监听的标示符; 参数event告诉内核需要监听的事件,event的结构如下:*/ struct epoll_event { __uint32_t events; //Epoll events epoll_data_t data; //User data variable };
3、 int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout) //等待事件的产生,函数返回需要处理的事件数目(该数目是就绪事件的数目,就是前面所说漂亮女孩的个数N)
因此,服务端epoll的时候,步骤如下:
1.调用epoll_create函数在Linux内核中创建一个事件表;
2.然后将文件描述符(监听套接字)添加到所创建的事件表中;
3.在主循环中,调用epoll_wait等待返回就绪的文件描述符集合;
4.分别处理就绪的事件集合
下面介绍下如何将一个socket添加到内核事件表中,如下:
//将文件描述符fd添加到epollfd标示的内核事件表中, 并注册EPOLLIN和EPOOLET事件,EPOLLIN是数据可读事件;EPOOLET表明是ET工作方式。最后将文件描述符设置非阻塞方式 /** * @param epollfd: epoll句柄 * @param fd: 文件描述符 * @param enable_et : enable_et = true, 采用epoll的ET工作方式;否则采用LT工作方式 **/ void addfd( int epollfd, int fd, bool enable_et ) { struct epoll_event ev; ev.data.fd = fd; ev.events = EPOLLIN; if( enable_et ) ev.events = EPOLLIN | EPOLLET; epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev); setnonblocking(fd); printf("fd added to epoll!\n\n"); }
相关文章推荐
- linux 死机 处理 reisub
- (大数据工程师学习路径)第一步 Linux 基础入门----命令执行顺序控制与管道
- Linux根文件系统详解
- [转载] 分析Linux内核创建一个新进程的过程
- DAY_18_linux/list.h
- LINUX系统安装
- Linux常用命令笔记
- (大数据工程师学习路径)第一步 Linux 基础入门----文件系统操作与磁盘管理
- linux 下 c++ 多线程的实现
- Linux命令学习之二
- linux syetem()函数
- Linux命令学习之一
- (大数据工程师学习路径)第一步 Linux 基础入门----文件打包与压缩
- linux下man时括号里的数字意义
- Darwin Streaming Server 在Linux (fedora)和window下的搭建
- Linux疑问---------文件系统的疑问---?????
- CentOS下安装Git
- linux内核的冒险md来源释义# 14raid5非条块读
- 新手的linux之旅 五、安装IE浏览器
- Linux操作系统-标准IO库(4)