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 ...
随机推荐
- Docker镜像拉不下来?试试这些
DaoCloud 加速器1.0(永久免费) DaoCloud是国内第一家Dock Hub加速器提供商 注意,加速器 2.0 需要使用 DaoCloud 自己的云服务器才可以使用.官方宣称会继续支持加速 ...
- Linux 修改本地时间 (centos为例)
1. tzselect [root@xxxx etc]# tzselect --- 选择时区命令 Please identify a location so that time zone rules ...
- Centos6.6安装docker
今天在虚拟机上体验一下docker, 操作系统:Centos6.6 内核版本:2.6 1. https://download.csdn.net/download/dujiaoyang000/10872 ...
- Python中getopt()函数的使用
在运行程序时,可能需要根据不同的条件,输入不同的命令行选项来实现不同的功能.目前有短选项和长选项两种格式.短选项格式为"-"加上单个字母选项:长选项为"--"加 ...
- Python @property 方法
考察 Student 类: class Student(object): def __init__(self, name, score): self.name = name self.score = ...
- Educational Codeforces Round 62
A. Detective Book 代码: #include <bits/stdc++.h> using namespace std; ; int N; int a[maxn]; ; in ...
- springmvc解决中文乱码问题
1 第一种情况(get接收参数): 最近在用solr做一个搜索服务,发布给手机和pc等客户端调用,调用方式为: http://www.ganbo.search/search?q="手机& ...
- Siamese network 孪生神经网络
Siamese network 孪生神经网络 https://zhuanlan.zhihu.com/p/35040994 https://blog.csdn.net/shenziheng1/artic ...
- elastalert 配置post告警方式(备忘)
最近在做把elk告警日志发送到kinesis 流,供后续数据分析处理使用........ 基于尽量不修改elastalert ,把修改工作放到接收端服务的原则.计划把elk的告警数据通过远程api ...
- Linux基本命令总结(七)
接上篇: 33,Linux中的kill命令用来终止指定的进程(terminate a process)的运行,是Linux下进程管理的常用命令.通常,终止一个前台进程可以使用Ctrl+C键,但是,对于 ...