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. Openstack (keystone 身份认证)

    keystone简介 keystone 是OpenStack的组件之一,用于为OpenStack家族中的其它组件成员提供统一的认证服务,包括身份验证.令牌的发放和校验.服务列表.用户权限的定义等等.云 ...

  2. TCP/IP__TCP协议

    1.定位:传输控制协议(Transmission Control Protocol),是一种面向连接的.可靠的.基于字节流的传输层通信协议. 2.原理:应用层向TCP层发送用于网间传输的.用8位字节表 ...

  3. 考研机试练习(KY2-KY10)

    KY2 成绩排序 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M 本题知识点: 排序 sort struct 题目描述 查找和排序 题目:输入任意(用户,成绩) ...

  4. 【函数分享】每日PHP函数分享(2021-2-5)

    array_column - 返回数组中指定的一列 说明: array_column ( array $input , mixed $column_key , mixed $index_key = n ...

  5. Codeforces Round #625 (Div. 2)

    Contest Info Practice Link Solved A B C D E F 4/6 O O Ø  Ø     O 在比赛中通过 Ø 赛后通过 ! 尝试了但是失败了 - 没有尝试 Sol ...

  6. HDU 3336——Count the string

    It is well known that AekdyCoin is good at string problems as well as number theory problems. When g ...

  7. hdu2818 Building Block

    Problem Description John are playing with blocks. There are N blocks (1 <= N <= 30000) numbere ...

  8. JavaScript——三

    任务: 其中的"options = options || {}"就代表如果options是一个真的对象,就使用它,否则就给他默认值 在Node函数中: 函数中的this指向wind ...

  9. Nginx基础 - 配置代理web服务

    1.反向代理及负载均衡Nginx实现负载均衡用到了proxy_pass代理模块核心配置,将客户端请求代理转发至一组upstream虚拟服务池. 1)upstream配置语法 Syntax: upstr ...

  10. OpenStack Train版-7.neutron网络服务概述

    网络服务NEUTRON概述 一.NEUTRON架构 OpenStack的网络服务neutron是整个OpenStack中最复杂的一个部分,它的基本架构是一个中心服务(neutron-server)外加 ...