IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    epoll 小解以及和select的区别

    klion26发表于 2014-09-26 14:01:22
    love 0

    前面写过 select 和 poll 的文章,在 Linux 下有一种更高效的 I/O 多路机制,那就是 epoll。epoll的高效和它的结构有关系(本文默认读者已经了解 select),首先 epoll 会把 select 的过程分成3个部分, epoll_create(), epoll_ctl() 和 epoll_wait。在 epoll_create 的过程中,会创建一个 eventpoll 结构体,这个结构体的部分定义如下

    struct eventpoll{
        ...  
        struct rb_root rbr; //红黑树,存储了所有添加到 epoll 中的事件
        struct list_head rdllist; // 双向链表保存通过 epoll_wait 返回给用户的满足条件的事件
        ...
    }

    这里的红黑树 rbr 存储了所有已经添加到 epoll 中的事件,如果使用 epoll_ctl 进行事件操作的时候,会在红黑树中进行查找,这个效率是很高的(红黑树是一颗自平衡二叉搜索树,查找事件 O(lgn))。双向链表 rdllist 则保存将要返回给用户的满足条件的事件。
    然后所有添加的事件都会和设备(如网卡)驱动程序建立回调关系,一旦相应事件发生就回调用这里的回调函数,然后回调函数就会把事件添加到上面的双向链表中去。因为最后返回时只需要查看链表是否有数据,这个就比 select 要高效很多
    然后最后是 epoll_wait.调用这个函数的时候,我们会等待一段时间(这段时间是由自己设置),这段时间过去之后,epoll 会自动返回双向链表中的事件,如果双向链表不为空,就把这里的事件复制到用户态内存中,同时将事件数量返回给用户。
    epoll 的基本功能差不多就这些,当然还有一个叫做触发模式的,epoll 分为两种触发模式{水平触发,边缘触发},区别就是水平触发的话,如果某一次没有处理,那么下一次还会返回给用户,但是边缘触发的话,只在事件发生时返回给用户一次,如果用户忽略掉了,那么后面就不会再返回给用户了。
    至于为什么 epoll 会比 select 要好用,大致有如下几个原因
    1. select 用的是 FD_SET进行操作,而 FD_SET 有上限限制(可以通过自己改源码进行修改),但是 epoll 没有这个限制
    2. select 会对所有的感兴趣的 fd 一个个去检查是否就绪,这样就行成了一个轮询,这个是比较慢的,而 epoll 则通过设置回调函数,在有事件发生的时候,将事件添加到双向链表中,最后只需要检查双向链表是否为空即可,这个也是很高效的。
    3. 还有 epoll_ctl 对事件进行操作时,会在红黑树中先查找是否存在,查找的过程也是很高效的。
    这样 epoll 就可以轻松处理百万级的并发处理了。
    epoll 的东西大致就这么一些,至于实际应用,这个需要看实际的情况了,这个没有经验,不敢妄谈。

    您可能也喜欢:

    select && poll 函数

    Linux命令行和Shell脚本编程2

    第一个Linux可装载模块

    Linux命令行和shell脚本编程笔记3

    Linux下的守护进程
    无觅



沪ICP备19023445号-2号
友情链接