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. 后台获取日期值,前台Js对日期进行操作

    需求描述: 方法一: 方法二: 一些标签常用隐藏方法: 需求描述: 在初始化页面的时候,需要根据系统当前的时间对前台JSP页面的某项进行值的初始化,若前台JSP标签没有相关可以初始化的属性,那么可以从 ...

  2. RIDE对应驱动下载

    https://blog.csdn.net/apollolkj/article/details/75408237

  3. YOLOv1论文解读

    摘要 我们提出一种新的目标检测算法--YOLO.以前有关目标检测的研究将检测转化成分类器来执行.然而,我们将目标检测框架化为空间分隔的边界框及相关的类概率的回归问题.在一次评估中,单个神经网络直接从整 ...

  4. HashMap源码(JDK1.8)-手动注释

    HashMap简介 HashMap是一种K-V映射的一种数据结构,通过K(key)值能实现在O(1)的时间复杂度下找到对应的V(value).JDK1.8之前,HashMap的底层数据结构是数组+链表 ...

  5. Java创建线程四种方式

    1.继承Thread类 public class MyThread extends Thread { public MyThread() { } public void run() { for(int ...

  6. LaTeX 环境安装&编译器配置

    推荐网站:https://www.latexstudio.net/articles/ (基本所有的latex疑惑都可以在这里得到解决) 入门视频:两小时短小精悍,让你轻松入门,https://www. ...

  7. fzu2178礼物分配 (状压+二分)

    Problem Description 在双胞胎兄弟Eric与R.W的生日会上,他们共收到了N个礼物,生日过后他们决定分配这N个礼物(numv+numw=N).对于每个礼物他们俩有着各自心中的价值vi ...

  8. Codeforces Round #667 (Div. 3) C. Yet Another Array Restoration (数学)

    题意:给你两个数字\(x\)和\(y\),让你构造一个长度为\(n\)的序列,要求包含\(x\)和\(y\),并且排序后相邻两项的差值相等. 题解:有排序后相邻两项的差值相等可知,构造的序列排序后一定 ...

  9. Java基础(第一期)

    Java基础 1.注释 Java中注释有三种: 单行注释 // 多行注释 /* */ 文本注释(用的较少) /** */ 书写注释是一个非常好的习惯 BAT 平时写代码一定要注意规范 //有趣的代码注 ...

  10. how to auto open demo and create it in a new codesandbox

    how to auto open demo and create it in a new codesandbox markdown & iframe https://ant.design/do ...