linux中epoll模型
epoll是linux内核为处理大批量文件描述符而作了改进的poll,是linux下IO复用select/poll的增强版本。
一、epoll的主要接口是:
1、创建
(1)int epoll_create(int maxfds);
maxfds是支持的最大句柄数。该函数会返回一个新的epoll句柄,之后的函数调用都用这个句柄来操作。用完之后,记得用close()关闭这个创建出来的epoll句柄,否则可能导致系统fd被耗尽。
(2)int epoll_reate1(int flag);
上面创建的方法在linux 2.6.8之后,maxfds是被忽略的,所以建议采用epoll_create1(0)这种方法。另外epoll_create1(EPOLLCLOEXEC)表示生成的epoll fd具有“执行后关闭”的特性。
2、事件注册
int epoll_ctl(int epfd,int op,int fd,struct epoll_event* event);
epoll的事件注册函数,它不同于select/poll在监听的时候告诉内核要监听什么事件,而是先注册要监听的事件类型。
(1)epfd为(1)返回的epoll句柄
(2)op表示动作,用三个宏来表示:
EPOLL_CTL_ADD:注册新的fd到epfd中
EPOLL_CTL_MOD:修改已注册的fd的监听事件
EPOLL_CTL_DEL:从epfd中删除一个fd
(3)fd为要监听的fd
(4)event为要监听的事件,结构如下:
struct epoll_event
{
__uint32_t events;
epoll_data_t data;
};
events可以是一下宏的集合:
EPOLLIN :表示对应的文件描述符可以读(包括对端SOCKET正常关闭);
EPOLLOUT:表示对应的文件描述符可以写;
EPOLLPRI:表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来);
EPOLLERR:表示对应的文件描述符发生错误;
EPOLLHUP:表示对应的文件描述符被挂断;
EPOLLET: 将EPOLL设为边缘触发(Edge Triggered)模式,这是相对于水平触发(Level Triggered)来说的。
EPOLLONESHOT:只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个socket的话,需要再次把这个socket加入到EPOLL队列里
3、等待事件发生
int epoll_wait(int epfd,struct epoll_event* events,int maxevents,int timeout);
等待事件发生,类似于select()调用。参数events用来从内核得到事件的集合,maxevents告诉内核这个events有多大,maxevents不能大于epoll_create时设置的size,参数timeout是超时时间(毫秒,0立即返回,-1将永久阻塞)。该函数返回需要处理的事件数目,如果返回0表示已超时。
二、epoll的两种工作模式
epoll默认的工作模式是Level Triggered,通过epoll_ctl可以设置epoll的工作模式为Edge Triggered。
LT(levet triggered)同时支持block和no-block socket。在该模式下,内核告诉你一个文件描述符是否就绪了,然后你可以对这个就绪的fd进行IO操作。如果你不作任何操作,内核还是会继续通知你的,所以,这种模式编程出错的可能性要小一点。传统的select/poll都是这种模型的代表。
ET(edge triggered)是高速工作方式,只支持non-block socket。在这种模式下,当描述符从未就绪变为就绪时,内核通过epoll告诉你。如果描述符没有再次发生IO操作(导致它再次变成未就绪),内核不会发送更多的通知。例如:ET模式下epoll_wait返回,当前缓存中接收到了2KB的数据,调用read读取1KB的数据。下次循环调用epoll_wai时将不会受到内核通知,将阻塞在这里,直到发生IO操作(如又收到数据)。当调用read或者write返回EAGAIN时,才需要挂起。但我们一般在处理循环读时,当read()返回的读到的数据长度小于请求的数据长度时,就可以确定此时缓冲中已没有数据了,也就可以认为此事读事件已处理完成。
三、epoll相对于select/poll的优势
1、epoll通过epoll_ctl注册监听的事件,而不像select/poll在每次循环调用select/poll函数时,设置监听事件,把fd集合从用户态拷贝到内核态),这个开销在fd很多时会很大。
2、select/poll在监听事件发生后,需要遍历所有fd,这个开销在fd很多时也很大,而epoll_wait返回的就是需要处理的事件。
3、select支持的最大文件描述符个数默认为1024,不适合处理大批量的文件描述符。而epoll就没有限制。
4、在并发连接数较大而活动连接数较小时,epoll比poll效率更高;而如果所有连接基本都是活跃的,比如一个高速LAN环境,epoll并不比select/poll有什么效率。
linux中epoll模型的更多相关文章
- Linux中epoll+线程池实现高并发
服务器并发模型通常可分为单线程和多线程模型,这里的线程通常是指“I/O线程”,即负责I/O操作,协调分配任务的“管理线程”,而实际的请求和任务通常交由所谓“工作者线程”处理.通常多线程模型下,每个线程 ...
- 聊聊 Linux 中的五种 IO 模型
本文转载自: http://mp.weixin.qq.com/s?__biz=MzAxODI5ODMwOA==&mid=2666538919&idx=1&sn=6013c451 ...
- linux epoll模型
原文:http://yjtjh.blog.51cto.com/1060831/294119 Linux I/O多路复用技术在比较多的TCP网络服务器中有使用,即比较多的用到select函数.Linux ...
- (OK) Linux epoll模型—socket epoll server client chat
http://www.cnblogs.com/venow/archive/2012/11/30/2790031.html http://blog.csdn.net/denkensk/article/d ...
- nginx中的epoll模型
要了解epoll模型,就要一个一个知识点由浅至深地去探索. 1.IO复用技术 IO流请求操作系统内核,有串行处理和并行处理两种概念. 串行处理是前面一个操作处理地时候,后面的所有操作都需要等待.因此, ...
- NIO学习笔记,从Linux IO演化模型到Netty—— 从BIO到epoll模型
本文不涉及具体代码,只分析Linux IO演化的心路历程,学习资料来源网络,不保证一定正确,若有错误,欢迎指出. BIO 服务端创建socket(80端口),文件描述符3号. 当线程调用accept时 ...
- Java基础(一):I/O多路复用模型及Linux中的应用
IO多路复用模型广泛的应用于各种高并发的中间件中,那么区别于其他模式他的优势是什么.其核心设计思想又是什么.其在Linux中是如何实现的? I/O模型 I/O模型主要有以下五种: 同步阻塞I/O:I/ ...
- Linux 中的五种 IO 模型
Linux 中的五种 IO 模型 在正式开始讲Linux IO模型前,比如:同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一 ...
- Linux 服务器IO模型 epoll
epoll模型 #include <unistd.h> #include <sys/types.h> /* basic system data types */ #includ ...
随机推荐
- SyntaxError: missing ) after argument list
消息 语法错误: 参数列表后面缺少 ) 错误类型 SyntaxError. 什么地方出错了? 有一个函数在调用时出现错误.这可能是一个错误,丢失运算符或者转义字符等. 示例 因为没有使用 ”+“ 操作 ...
- HDU 3901 Wildcard
题目:Wildcard 链接:http://acm.hdu.edu.cn/showproblem.php?pid=3901 题意:给一个原串(只含小写字母)和一个模式串(含小写字母.?.* ,*号可替 ...
- springboot 出现 Connection refused: connect
总结网上的方法再结合我自己的方法 1. springCloud com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectEx ...
- vim编辑器的命令总结
1. 设置显示行数 :set nu 2. 复制第100至第103行的代码
- C#、Java和JS实现SHA256+BASE64加密总结
C#.Java和JS实现SHA256+BASE64加密总结 --莫非(www.muphy.me) 原理 首先,通过编码格式(UTF-8.ASCII等,如果含有汉字等字符,编码格式不同加密结果也不同)获 ...
- pycharm项目上传到Github
使用本地代码直接share到github上过程中出现了一个问题: Successfully created project 'xxx' on GitHub, but initial push fail ...
- 2.4 random 模块
- 小程序运行报错:errMsg: "request:fail url not in domain list"
错误原因: 报错提示说请求的url不在域名列表里,应该是还没有配置服务器域名 解决方法: 可点击开发者工具右上角 详情-项目设置-不校验合法域名.web-view(业务域名).TLS 版本以及 HTT ...
- 阶梯Nim问题
问题形式 有\(n\)个位置\(1...n\),每个位置上有\(a_i\)个石子.有两个人轮流操作.操作步骤是:挑选\(1...n\)中任一一个存在石子的位置\(i\),将至少1个石子移动至\(i-1 ...
- Python的编码和解码
Python的编码和解码 在不同的国家,存在不同的文字,由于现在的软件都要做到国际化通用,所以必须要有一种语言或编码方式,来实现各种编码的解码,然后重新编码. 在西方国家,没有汉字,只有英文,所以最开 ...