zoukankan      html  css  js  c++  java
  • epoll简介

    1.epoll简介

    epoll是I/O事件通知工具,与select/poll相比,epoll最大的好处在于它不会随着监听fd数目的增长而效率降低。
    epoll API既可以用作edge触发的接口,也可以用作level触发,并且对于监听大量的文件描述符同样有很好的性能。

    因为内核中的select采用轮询实现的,轮询的fd数目越多,耗时越多。并且,在linux/posix_types.h中#define __FD_SETSIZE 1024
    即select最多同时监听1024个fd,当然,可以通过修改头文件再重编译内核来扩大这个数目,但这似乎并不治本。


    2.epoll使用方法

    (1)使用epoll_create()创建一个epoll实例。
    (2)通过epoll_ctl()将想监听的文件描述符和其事件注册进epoll实例中。
    POLL_CTL_ADD:注册目标文件描述符,并将事件event与相关联。
    EPOLL_CTL_MOD: 更改与目标文件描述符fd关联的事件event。
    EPOLL_CTL_DEL: 溢出指定的FD

    可设置的监听事件类型:
    EPOLLIN :表示对应的文件描述符可以读(包括对端SOCKET正常关闭);
    EPOLLOUT:表示对应的文件描述符可以写;
    EPOLLPRI:表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来);
    EPOLLERR:表示对应的文件描述符发生错误;
    EPOLLHUP:表示对应的文件描述符被挂断;
    EPOLLET: 将EPOLL设为边缘触发(Edge Triggered)模式,这是相对于水平触发(Level Triggered)来说的。
    EPOLLONESHOT:只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个socket的话,需要再次把这个socket加入到EPOLL队列里

    (3)通过epoll_wait()来阻塞监听I/O事件。


    3.edge触发和level触发的区别

    epoll事件分发接口能够表现为边缘触发(ET)和水平触发(LT)。 两种机制之间的差异可以描述如下。 假设发生这种情况:
    ①表示管道读取端(rfd)的文件描述符在epoll实例上注册。
    ②管道的写入端在管道的wfd上写入2kB的数据。
    ③完成对epoll_wait()的调用,将rfd作为就绪文件描述符返回。
    ④管道读取端先从rfd读取1kB数据。
    ⑤完成对epoll_wait()的调用。

    如果已使用EPOLLET(边缘触发)标志将rfd文件描述符添加到epoll接口,则尽管文件输入缓冲区中仍存在可用数据,但在步骤⑤中的对
    epoll_wait()的调用可能会挂起。原因是边缘触发模式仅在受监视文件描述符发生更改时才传递事件。因此在步骤5中对epoll_wait()的调用
    可能会无限期地被阻塞。

    用作水平触发时(默认是水平触发的,未指定EPOLLET时),epoll只是一个更快的poll()。


    4.注意事项

    使用epoll的应用程序应使用非阻塞(O_NONBLOCK)文件描述符(select/poll应该也是一样的)建议方法如下:
    a.使用非阻塞文件描述符;
    b.仅在read()或write()之后检查errno值是否是EAGAIN。(若是非阻塞的读,读完了返回-EAGAIN,缓存区写满了返回-EAGAIN)


    5.EPOLL_CTL_MOD标志
    即使使用边缘触发的epoll,也可以在收到多个事件,调用者可以选择指定EPOLLONESHOT标志,告诉epoll在收到
    epoll_wait()事件后禁用关联的文件描述符。 当指定了EPOLLONESHOT标志时,若想再次使用epoll来监听这个描述符调用者
    需要使用epoll_ctl(EPOLL_CTL_MOD)重新安装此文件描述符。

    6.epoll的/proc接口
    /proc/sys/fs/epoll/max_user_watches 用于限制epoll()监听的最大文件描述符的个数,用于限制对内核内存的使用。默认是4%的内存占用。


    可参考:
    高并发网络编程之epoll详解:https://blog.csdn.net/shenya1314/article/details/73691088
    epoll 总结:https://blog.csdn.net/xiangguiwang/article/details/80659826

  • 相关阅读:
    终端创建scrapy项目时报错(转)
    redis的一些命令
    pom.xml中build标签
    spring与mybatis四种整合方法
    linux lsof/netstat查看进程和端口号相关命令:
    ps -ef |grep 输出的具体含义
    java web项目在linux部署、启动,查看系统配置常用的linux命令总结
    linux mysql操作命令大全
    mysql中between...and..的使用,及时间范围的查询
    mysql中if()函数使用
  • 原文地址:https://www.cnblogs.com/hellokitty2/p/10799522.html
Copyright © 2011-2022 走看看