Linux平台的epoll通信模型

·概要:

    Epoll是在linux2.6内核中加入的作为处理大批量句柄而改进的poll。这是Linux平台的处理异步I/O的高效模型。

    记得在网上看过一个资料说:select就像是鬼子进村时一遍遍的询问"鬼子进村了么?",而epoll则像是派出一个人监视鬼子是否进村了。虽然现在还不能通过两者体会select和epoll的本质不同,暂且记录下来。

·要点:

基础:

--原理:

    epoll适用的模型是Reactor设计模式--可通过Reactor深入理解。

    相比于IOCP,epoll仅仅是一个异步事件通知机制,本身并不做任何的I/O操作而是会得到可以进行I/O操作的通知。而IOCP不仅是在I/O操作完成后在进行通知同时通过内部的线程池封装了一部分I/O控制逻辑。

    因此epoll是串行处理,同时可以通过配合线程池来发挥最大作用。

--头文件:

    #include <sys/epoll.h>

--数据结构:

    typedef union epoll_data{

          void * ptr;

          int fd;

          __uint32_t u32;

          __uint64_t u64;

    }epoll_data_t;

    struct epoll_event{

          __uint32_t events;

          epoll_data_t data;

    };

      其中可以通过epoll_data中的ptr传递应用层数据;

--接口函数:

    用到的接口函数有:epoll_create(),epoll_ctl(),epoll_wait():

epoll_create函数:

    原型:int epoll_create(int size);

    功能:生成一个epoll专用的文件描述符。

    参数:指定生成描述符的最大范围--参数的设定没有好的参考。

epoll_ctl函数:

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

    功能:可注册、修改、删除epoll事件。

    返回值:成功返回0,否则返回-1.

    参数:epfd是epoll_create()创建的epoll句柄,op取值{EPOLL_CTL_ADD,

            EPOLL_CTL_MOD,EPOLL_CTL_DEL}的操作,fd是关联事件的对象,

            event则是轮询时被通知的时间类型。

epoll_wait函数:

    原型:int epoll_wait(int epfd,struct epoll_event* events,

                              int maxevents,int timeout);

    功能:进行I/O就绪轮询操作。

    返回值:就绪的时间数目--即events数组的大小。

    参数:epfd是epoll句柄,events是就绪的事件数组,maxevents则是每次

          可处理的event的最大数目--不能比epoll_create(int size)中参数size

          大,timeout则是超时控制。

--说明:

    首先需要说明的是epoll句柄也是系统资源,在使用完后需要close()释放资源。

    其次需要说明的是event_data中event的取值:

         EPOLLIN--可读(包括对端SOCKET正常关闭)

         EPOLLOUT--可写

         EPOLLPRI--有紧急数据可读(表示有带外数据到来)

         EPOLLERR--发生错误

         EPOLLHUP--被挂断

         EPOLLET--边缘触发模式

         EPOLLONESHOT--只监听一次,当监听完这次事件后如需要继续监听的话

                                 还需要再次将SOCKET加入到EPOLL队列中。

        epoll有两种工作方式:

             LT(level triggered)是缺省方式,同时支持block和no-block。

                   特点是如果不处理事件的话会持续进行通知—与select/poll一样;

             ET(edge triggered)是高速方式,只支持no-block socket。

                    特点是只通知一次就绪事件然后假设不需要在提示。

--常用模型:

    首先要创建并配置epoll句柄;

    然后创建一个监听socket并注册到epoll中;

    最后进入一个{调用epoll_wait==》处理就绪事件}的循环中。

    其中,可以在处理就绪事件过程中将处理交给线程池做来进行扩展。

·小结:

    有很多库(知道的有boost.asio和libevent)在linux平台都是基于epoll的。

    EPOLL算是Linux平台网络编程的基础吧。

原文地址:https://www.cnblogs.com/davidyang2415/p/2453365.html