美文网首页
面试题 —— select poll epoll

面试题 —— select poll epoll

作者: 昵称不能全是数字 | 来源:发表于2019-05-15 23:02 被阅读0次

    1.select、poll、epoll

    https://segmentfault.com/a/1190000003063859
    这个讲的很好,就是图都挂了

    • 阻塞 I/O(blocking IO)
    • 非阻塞 I/O(nonblocking IO) 返回error
    • I/O 多路复用( IO multiplexing)select、poll、epoll
    • 信号驱动 I/O( signal driven IO)
    • 异步 I/O(asynchronous IO)

    如果处理的连接数不是很高的话,使用select/epoll的web server不一定比使用multi-threading + blocking IO的web server性能更好,可能延迟还更大。select/epoll的优势并不是对于单个连接能处理得更快,而是在于能处理更多的连接。)

    当用户进程调用了select,那么整个进程会被block,而同时,kernel会“监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用read操作,将数据从kernel拷贝到用户进程

    异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间

    select

    int select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
    

    当select函数返回后,可以 通过遍历fd_set,来找到就绪的描述符。
    select目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点。select的一 个缺点在于单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024,可以通过修改宏定义甚至重新编译内核的方式提升这一限制,但 是这样也会造成效率的降低。

    select()中的第一个参数,给出最大监听的fd+1的值

    poll

    int poll (struct pollfd *fds, unsigned int nfds, int timeout);
    

    不同与select使用三个位图来表示三个fdset的方式,poll使用一个 pollfd的指针实现。

    struct pollfd {
        int fd; /* file descriptor */
        short events; /* requested events to watch */
        short revents; /* returned events witnessed */
    };
    

    和select函数一样,poll返回后,需要轮询pollfd来获取就绪的描述符
    select和poll都需要在返回后,通过遍历文件描述符来获取已经就绪的socket。事实上,同时连接的大量客户端在一时刻可能只有很少的处于就绪状态,因此随着监视的描述符数量的增长,其效率也会线性下降

    epoll

    epoll操作过程需要三个接口,分别如下:

    int epoll_create(int size);//创建一个epoll的句柄,size用来告诉内核这个监听的数目一共有多大
    int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
    int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
    
    struct epoll_event {
      __uint32_t events;  /* Epoll events */
      epoll_data_t data;  /* User data variable */
    };
    //events可以是以下几个宏的集合:
    EPOLLIN :表示对应的文件描述符可以读(包括对端SOCKET正常关闭);
    EPOLLOUT:表示对应的文件描述符可以写;
    EPOLLPRI:表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来);
    EPOLLERR:表示对应的文件描述符发生错误;
    EPOLLHUP:表示对应的文件描述符被挂断;
    EPOLLET: 将EPOLL设为边缘触发(Edge Triggered)模式,这是相对于水平触发(Level Triggered)来说的。
    EPOLLONESHOT:只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个socket的话,需要再次把这个socket加入到EPOLL队列里
    

    当创建好epoll句柄后,它就会占用一个fd值,在linux下如果查看/proc/进程id/fd/,是能够看到这个fd的,所以在使用完epoll后,必须调用close()关闭,否则可能导致fd被耗尽。

    https://www.cnblogs.com/Anker/p/3265058.html

    select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的
    I/O多路复用技术的最大优势是系统开销小,系统不必创建进程/线程,也不必维护这些进程/线程,从而大大减小了系统的开销。

    区别:

    select

    1. 被监控的fds需要从用户空间拷贝到内核空间
    2. 被监控的fds集合中,只要有一个有数据可读,整个socket集合就会被遍历一次调用sk的poll函数收集可读事件
    3. select支持的文件描述符数量太小了,默认是1024

    epoll

    1. epoll事先通过epoll_ctl()来注册一 个文件描述符,一旦基于某个文件描述符就绪时,内核会采用类似callback的回调机制,迅速激活这个文件描述符,当进程调用epoll_wait() 时便得到通知
    2. IO的效率不会随着监视fd的数量的增长而下降。epoll不同于select和poll轮询的方式,而是通过每个fd定义的回调函数来实现的。只有就绪的fd才会执行回调函数。

    相关文章

      网友评论

          本文标题:面试题 —— select poll epoll

          本文链接:https://www.haomeiwen.com/subject/ftpsaqtx.html