`
pingwei000
  • 浏览: 58970 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Epoll工作模式详解(转)

阅读更多

我们目前的网络模型大都是epoll的,因为epoll模型会比select模型性能高很多, 尤其在大连接数的情况下,作为后台开发人员需要理解其中的原因。

select/epoll的特点

select的特点:select 选择句柄的时候,是遍历所有句柄,也就是说句柄有事件响应时,select需要遍历所有句柄才能获取到哪些句柄有事件通知,因此效率是非常低。但是如果连接很少的情况下, select和epoll的LT触发模式相比, 性能上差别不大。

这里要多说一句,select支持的句柄数是有限制的, 同时只支持1024个,这个是句柄集合限制的,如果超过这个限制,很可能导致溢出,而且非常不容易发现问题, TAF就出现过这个问题, 调试了n天,才发现:)当然可以通过修改linux的socket内核调整这个参数。

epoll的特点:epoll对于句柄事件的选择不是遍历的,是事件响应的,就是句柄上事件来就马上选择出来,不需要遍历整个句柄链表,因此效率非常高,内核将句柄用红黑树保存的。

对于epoll而言还有ET和LT的区别,LT表示水平触发,ET表示边缘触发,两者在性能以及代码实现上差别也是非常大的。

epoll的LT和ET的区别

LT:水平触发,效率会低于ET触发,尤其在大并发,大流量的情况下。但是LT对代码编写要求比较低,不容易出现问题。LT模式服务编写上的表现是:只要有数据没有被获取,内核就不断通知你,因此不用担心事件丢失的情况。

ET:边缘触发,效率非常高,在并发,大流量的情况下,会比LT少很多epoll的系统调用,因此效率高。但是对编程要求高,需要细致的处理每个请求,否则容易发生丢失事件的情况。

下面举一个列子来说明LT和ET的区别(都是非阻塞模式,阻塞就不说了,效率太低):

采用LT模式下, 如果accept调用有返回就可以马上建立当前这个连接了,再epoll_wait等待下次通知,和select一样。

但是对于ET而言,如果accpet调用有返回,除了建立当前这个连接外,不能马上就epoll_wait还需要继续循环accpet,直到返回-1,且errno==EAGAIN,TAF里面的示例代码:

if(ev.events & EPOLLIN)

{

    do

    {

        struct sockaddr_in stSockAddr;

        socklen_t iSockAddrSize = sizeof(sockaddr_in);

        TC_Socket cs;

        cs.setOwner(false);

        //接收连接

        TC_Socket s;

        s.init(fd, false, AF_INET);

        int iRetCode = s.accept(cs, (struct sockaddr *) &stSockAddr, iSockAddrSize);

        if (iRetCode > 0)

        {

            …建立连接

        }

        else

        {

            //直到发生EAGAIN才不继续accept

            if(errno == EAGAIN)

            {

                break;

            }

        }

    }while(true);

}

同样,recv/send等函数, 都需要到errno==EAGAIN

从本质上讲:与LT相比,ET模型是通过减少系统调用来达到提高并行效率的。

epoll ET详解

ET模型的逻辑:内核的读buffer有内核态主动变化时,内核会通知你, 无需再去mod。写事件是给用户使用的,最开始add之后,内核都不会通知你了,你可以强制写数据(直到EAGAIN或者实际字节数小于 需要写的字节数),当然你可以主动mod OUT,此时如果句柄可以写了(send buffer有空间),内核就通知你。

这里内核态主动的意思是:内核从网络接收了数据放入了读buffer(会通知用户IN事件,即用户可以recv数据)

并且这种通知只会通知一次,如果这次处理(recv)没有到刚才说的两种情况(EAGIN或者实际字节数小于 需要读写的字节数),则该事件会被丢弃,直到下次buffer发生变化。

与LT的差别就在这里体现,LT在这种情况下,事件不会丢弃,而是只要读buffer里面有数据可以让用户读,则不断的通知你。

另外对于ET而言,当然也不一定非send/recv到前面所述的结束条件才结束,用户可以自己随时控制,即用户可以在自己认为合适的时候去设置IN和OUT事件:

1 如果用户主动epoll_mod OUT事件,此时只要该句柄可以发送数据(发送buffer不满),则epoll

_wait就会响应(有时候采用该机制通知epoll_wai醒过来)。

2 如果用户主动epoll_mod IN事件,只要该句柄还有数据可以读,则epoll_wait会响应。

这种逻辑在普通的服务里面都不需要,可能在某些特殊的情况需要。 但是请注意,如果每次调用的时候都去epoll mod将显著降低效率,已经吃过几次亏了!

因此采用et写服务框架的时候,最简单的处理就是:

建立连接的时候epoll_add IN和OUT事件, 后面就不需要管了

每次read/write的时候,到两种情况下结束:

1 发生EAGAIN

2 read/write的实际字节数小于 需要读写的字节数

对于第二点需要注意两点:

A:如果是UDP服务,处理就不完全是这样,必须要recv到发生EAGAIN为止,否则就丢失事件了

因为UDP和TCP不同,是有边界的,每次接收一定是一个完整的UDP包,当然recv的buffer需要至少大于一个UDP包的大小

随便再说一下,一个UDP包到底应该多大?

对于internet,由于MTU的限制,UDP包的大小不要超过576个字节,否则容易被分包,对于公司的IDC环境,建议不要超过1472,否则也比较容易分包。

B 如果发送方发送完数据以后,就close连接,这个时候如果recv到数据是实际字节数小于读写字节数,根据开始所述就认为到EAGIN了从而直接返回,等待下一次事件,这样是有问题的,close事件丢失了!

因此如果依赖这种关闭逻辑的服务,必须接收数据到EAGIN为止,例如lb。

分享到:
评论

相关推荐

    linux epoll机制详解

    主要介绍了linux epoll机制详解,介绍了select()和poll() IO多路复用模型,epoll IO多路复用模型实现机制,epoll的接口和工作模式等相关内容,小编觉得还是挺不错的,这里分享给大家,需要的朋友可以参考下

    epoll学习资料

    linux下的Tcp服务器,采用的是Epoll模式,linux下用epoll实现的udp服务器例子

    LinuxIO模式及select、poll、epoll详解

    看到这篇文章说明你已经从老版本升级到Ubuntu16.04或进行了全新安装,在安装好Ubuntu16.04LTS之后建议大家先做如下15件事。无论你是刚加入Ubuntu行列的新用户,还是有经验的老用户,你都会发现一些非常有用的调整和...

    linux C语言 网络编程教程及源码

    16、Linux网络编程16——I/O复用之epoll详解 17、Linux网络编程17——tcp并发服务器(多进程) 18、Linux网络编程18——tcp并发服务器(多线程) 19、Linux网络编程——tcp高效并发服务器(select实现) 20、Linux...

    Nginx服务器Nginx.com配置文件详解

    在此记录下Nginx服务器nginx.conf的配置文件...#工作模式及连接数上限 events { use epoll; #epoll是多路复用IO(I/O Multiplexing)中的一种方式,但是仅用于linux2.6以上内核,可以大大提高nginx的性能 worker_connectio

    Linux下几种并发服务器的实现模式(详解)

    3>select+多线程模式 并发服务器的三种实现方式 1.多进程并发服务器 是指TCP连接后,每一个客户机的请求并不由服务器直接处理,而是由服务器创建一个子进程来处理 2.多线程并发服务器 多进程服务器是对多进程的服

    Linux高性能服务器编程

    9.1.3 处理带外数据 9.2 poll系统调用 9.3 epoll系列系统调用 9.3.1 内核事件表 9.3.2 epoll_wait函数 9.3.3 LT和ET模式 9.3.4 EPOLLONESHOT事件 9.4 三组IO复用函数的比较 9.5 IO复用的高级应用一:非阻塞...

    chensongpoixs.github.io:陈松的技术博客

    Welcome to GitHub Pages 一, 博客使用 /_post/ --- layout: post title: 网络协议详解 subtitle: ARP协议,DNS协议,IP协议,TCP协议,IP路由和TCP状态转换图 ...subtitle: epoll的两种模式-LT模式和高速度

    [14本经典Android开发教程]-8-Linux内核阅读心得体会

    读核感悟 内存管理 free命令详解 58 读核感悟 文件读写 2 6 9内核中的AIO 59 1 AIO概述 59 2 内核态AIO的使用 61 读核感悟 文件读写 内核态AIO相关结构体 61 1 内核态AIO操作相关信息 61 2 AIO上下文: 63 3 AIO ...

    python网络编程

    课程介绍 ⽹络概述、udp ⽹络通信概述 tcp/ip简介 端⼝ ...并发服务器、HTTP协议 单进程服务器 多进程服务器 多线程服务器 单进程服务器-⾮堵塞模式 单进程服务器-select版 单进程服务器-epoll版 多任务实现-协程

    详解socket阻塞与非阻塞,同步与异步、I/O模型

    例如普通B/S模式(同步):提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事 异步: 异步的概念和同步相对。当c端一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的...

    Nginx配置文件nginx.conf详细说明

    在此记录下Nginx服务器nginx.conf的配置文件说明, 部分...#工作模式及连接数上限 events { use epoll; #epoll是多路复用IO(I/O Multiplexing)中的一种方式,但是仅用于linux2.6以上内核,可以大大提高nginx的性能 wor

    Redis中事件驱动模型示例详解

    前言 Redis 是一个事件驱动的内存数据库,服务器需要...Redis 基于 Reactor 模式开发了自己的事件处理器。 这里就先展开讲一讲 Reactor 模式。看下图: “I/O 多路复用模块”会监听多个 FD ,当这些FD产生,accept,r

    Nginx的nginx.conf配置文件中文注释说明

    代码如下:  #运行用户 ...   #启动进程,通常设置成和cpu的数量相等 ... #工作模式及连接数上限  events {  use epoll; #epoll是多路复用IO(I/O Multiplexing)中的一种方式,但是仅用于linux2.6以上内

    python入门到高级全栈工程师培训 第3期 附课件代码

    09 select与epoll的实现区别 第36章 01 异步IO 02 selectors模块介绍 03 selectors模块应用 04 作业介绍 第37章 01 selctors实现文件上传与下载 02 html的介绍 03 html文档树的概念 04 meta标签以及一些基本标签...

    Linux内核阅读

    读核感悟-内存管理-free命令详解.............................................58 读核感悟-文件读写-2.6.9内核中的AIO.........................................59 1 AIO概述......................................

    Linux多线程服务端编程:使用muduo C++网络库

    3.3.3推荐模式. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . 64 3.4进程间通信只用TCP . . . . . . . . . . . . . . .. . . . . . . . . . . . . . 65 3.5多线程服务器的适用场合. . . . . . . ....

Global site tag (gtag.js) - Google Analytics