epoll通过下面3个epoll系统调用为用户提供服务。

(1)epoll_create系统调用

epoll_create在C库中的原型如下:

int epoll_create(int size);

epoll_create返回一个句柄,之后epoll的使用都将依靠这个句柄来标识。参数size是告诉epoll所要处理的大致事件数目。不再使用epoll时,必须调用close关闭句柄。

注:size参数只是告诉内核这个epoll对象会处理的事件大致数目,而不是能够处理的事件的最大个数。在Linux最新的一些内核版本的实现中,这个size参数没有任何意义。

(2)epoll_ctl系统调用

epoll_ctl在C库中的原型如下:

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

epoll_ctl向epoll对象中添加、修改或者删除感兴趣的事件,返回0表示成功,否则返回-1,此时需要根据errno错误码判断错误类型。epoll_wait方法返回的事件必然是通过epoll_ctl添加到epoll中的。

参数epfd是epoll_create返回的句柄,而op参数的意义见表:

op的取值 意义
EPOLL_CTL_ADD 添加新的事件到epoll中
EPOLL_CTL_MOD 修改epoll中的事件
EPOLL_CTL_DEL 删除epoll中的事件

第3个参数fd是待监测的连接套接字,第4个参数是在告诉epoll对什么样的事件感兴趣,它使用了epoll_event结构体,如下是epoll_event的定义:

struct epoll_event {

  __uint32_t events;

  epoll_data_t data;

};

events的取值如下:

events取值 意义
EPOLLIN 表示对应的连接上有数据可读(TCP连接的远端主动关闭连接,也相当于可读事件,因为需要处理发送来的FIN包)
EPOLLOUT 表示对应的连接上可写入数据发送(主动向上游服务器发起非阻塞的TCP连接,连接建立成功的事件相当于可写事件)
EPOLLRDHUP 表示TCP连接的远端关闭或半关闭连接
EPOLLPRI 表示对应的连接上有紧急的数据需要读取
EPOLLERR 表示对应的连接发生错误
EPOLLHUP 表示对应的连接被挂起
EPOLLET 表示将触发方式设置为边缘触发ET,系统默认为水平触发LT
EPOLLONESHOT 表示对这个事件智处理一次,下次需要处理时需重新加入epoll

而data成员是一个epoll_data联合,其定义如下:

typedef union epoll_data {

  void *ptr;

  int fd;

  uint32_t u32;

  uint64_t u64;

}epoll_data_t;

可见,这个data成员还与具体的使用方式有关。

(3) eplll_wait系统调用

epoll_wait在C库中的原型如下:

int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

收集在epoll监控的事件中已经发生的事件,如果epoll中没有任何一个事件发生,则最多等待timeout毫秒后返回。epoll_wait的返回值表示当前发生的事件个数,如果返回0,则表示本次调用中没有事件发生,如果返回-1,则表示出现错误,需要检查errno错误码判断错误类型。

第1个参数epfd是epoll的描述符。

第2个参数events则是分配好的epoll_event结构体数组,epoll将会把发生的事件复制到events数组中(events不可以是空指针,内核只负责把数据复制到这个events数组中,不会去帮我们在用户态中分配内存。内核这种做法效率很高)。

第3个参数maxevents表示本次可以返回的最大事件数目,通常maxevents参数与预分配的events数组的大小是相等的。

第4个参数timeout表示在没有检测到事件发生时最多等待事件,单位毫秒,如果timeout为0,则表示epoll_wait在rdllist为空时,立刻返回,不会等待。

epoll有两种工作模式:LT(水平触发)模式和ET(边缘触发)模式。默认情况下epoll采用LT模式工作,这时可以处理阻塞和非阻塞套接字,上表中EPOLLET表示可以将一个事件改为ET模式。ET模式的效率比LT模式的效率高,它只支持非阻塞套接字。ET模式与LT模式的区别在于:

当一个新的事件到来时,ET模式下当然可以从epoll_wait调用中获取到这个事件,可是如果这次如果没有把这个事件对应的套接字缓冲区处理完,在这个套接字没有新的事件再次到来时,在ET模式下是无法再次从epoll_wait调用中获取这个事件的;

而LT模式则相反,只要一个事件对应的套接字缓冲区还有数据,就总能从epoll_wait中获取这个事件。

因此在LT模式下开发基于epoll的应用要简单一些,不太容易出错,而在ET模式下事件发生时,如果没有彻底地将缓冲区数据处理完,则会导致缓冲区中的用户请求得不到响应。

默认情况下Nginx是通过ET模式使用epoll的。

epoll使用的更多相关文章

  1. 从I/O复用谈epoll为什么高效

    上一篇文章中,谈了一些网络编程的基本概念.在现实使用中,用的最多的就是I/O复用了,无非就是select,poll,epoll 很多人提到网络就说epoll,认为epoll效率是最高的.单纯的这么认为 ...

  2. select、poll、epoll之间的区别总结

    select.poll.epoll之间的区别总结 05/05. 2014 select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪 ...

  3. (转载) Linux IO模式及 select、poll、epoll详解

    注:本文是对众多博客的学习和总结,可能存在理解错误.请带着怀疑的眼光,同时如果有错误希望能指出. 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案 ...

  4. linux下select/poll/epoll机制的比较

    select.poll.epoll简介 epoll跟select都能提供多路I/O复用的解决方案.在现在的Linux内核里有都能够支持,其中epoll是Linux所特有,而select则应该是POSI ...

  5. epoll LT/ET 深度剖析

    EPOLL事件的两种模型: Level Triggered (LT) 水平触发 .socket接收缓冲区不为空 有数据可读 读事件一直触发 .socket发送缓冲区不满 可以继续写入数据 写事件一直触 ...

  6. 非阻塞/异步(epoll) openssl

    前段时间在自己的异步网络框架handy中添加openssl的支持,当时在网络上搜索了半天也没有找到很好的例子,后来自己慢慢的摸索,耗费不少时间,终于搞定.因此把相关的资料整理一下,并给出简单的例子,让 ...

  7. select,epoll,poll比较

    介绍和比较 http://www.cnblogs.com/maociping/p/5132583.html 比较 http://www.dataguru.cn/thread-336032-1-1.ht ...

  8. Linux epoll

    一. epoll函数集 epoll主要有三个函数: 1. int epoll_create(int size); 创建一个epoll的句柄,size用来告诉内核这个监听的数目一共有多大.这个参数不同于 ...

  9. linux下epoll实现机制

    linux下epoll实现机制 原作者:陶辉 链接:http://blog.csdn.net/russell_tao/article/details/7160071 先简单回顾下如何使用C库封装的se ...

  10. select、poll、epoll之间的区别总结[整理]

    select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作.但select ...

随机推荐

  1. Spring Boot整合Spring Data JPA

    1.JPA 2.Spring Data JPA 3.导入依赖 4.连接数据库 5.实体类 6.Repository 7.测试 1.JPA JPA是Java Persistence API的简称,中文名 ...

  2. 2019牛客暑期多校训练营(第二场) H-Second Large Rectangle(单调栈)

    题意:给出由01组成的矩阵,求求全是1的次大子矩阵. 思路: 单调栈 全是1的最大子矩阵的变形,不能直接把所有的面积存起来然后排序取第二大的,因为次大子矩阵可能在最大子矩阵里面,比如: 1 0 0 1 ...

  3. hdu5726 GCD(gcd +二分+rmq)

    Problem Description Give you a sequence of N(N≤100,000) integers : a1,...,an(0<ai≤1000,000,000). ...

  4. POJ - 2406 Power Strings (后缀数组DC3版)

    题意:求最小循环节循环的次数. 题解:这个题其实可以直接用kmp去求最小循环节,然后在用总长度除以循环节.但是因为在练后缀数组,所以写的后缀数组版本.用倍增法会超时!!所以改用DC3法.对后缀数组还不 ...

  5. Educational Codeforces Round 89 (Rated for Div. 2) C Palindromic Paths

    题目链接:Palindromic Paths 题意: 给你一个n行m列的矩阵,这个矩阵被0或者1所填充,你需要从点(1,1)走到点(n,m).这个时候会有很多路径,每一条路径对应一个01串,你可以改变 ...

  6. Network POJ - 3694 无向图找桥

    题意: 给你一个无向图,你需要找出来其中有几个桥 桥: 1.存在重边必定不为桥 2.low[v]>dfn[u] 代码: //题意很清晰 //就是这个需要先找出来原无向图中的桥个数,然后在判断添加 ...

  7. 无所不能的Embedding6 - 跨入Transformer时代~模型详解&代码实现

    上一章我们聊了聊quick-thought通过干掉decoder加快训练, CNN-LSTM用CNN作为Encoder并行计算来提速等方法,这一章看看抛开CNN和RNN,transformer是如何只 ...

  8. 【一天一个基础系列】- java之泛型篇

    简介 说起各种高级语言,不得不谈泛型,当我们在使用java集合的时候,会发现集合有个缺点:把一个对象"丢进"集合之后,集合就会"忘记"这个对象的数据类型,当再次 ...

  9. 微信小程序swiper实现 句子控app首页滑动卡片

    微信小程序swiper实现 句子控app首页滑动卡片 引言:最近看到句子控APP首页的效果很清新,可是发现他的微信小程序端没有实现这个功能,我看了一下难度不大,于是尝试着去实现. 实现效果如下: 1. ...

  10. Python:装饰器是如何调用的

    应用举例:(1)装饰器 # 装饰器的调用: # 一旦用上装饰器会: # 第一步:调outer函数 # 第二步:被装饰的函数play_game会被当作参数fn给outer # 第三步:最后调用play_ ...