• Selector和Epoll区别


    Selector和Epoll区别

    select原理

    原理还是轮询所有文件描述符

    1. 将文件描述符集合fd_set从用户空间拷贝到内核空间,进入内核态
    2. 遍历所有文件描述符,对每个文件描述符调用poll(),该函数返回一组标准的掩码,其各个位指示相应的文件描述符的就绪状态(全为0表示没有任何事件就绪)
    3. 根据掩码对fd_set进行赋值,如果没有文件就绪且时间未到则会进入短暂的睡眠
    4. 然后恢复并再次对fd_set轮询调用poll(),直到有文件就绪或者时间到达。
    5. 如果有文件就绪,函数就返回,将fd_set再次从内核空间拷贝到用户空间,系统返回用户态,用户就可以对相应的文件进行读和写了

    epoll原理

    epoll_create()

    该函数建立一个epoll句柄

    内核在epoll文件系统中建立了一个 file节点
    在内核缓冲区 Cache 中建立一棵红黑树和一条双向链表。

    红黑树用来存储以后 epoll_ctl() 注册的文件描述符

    双向链表用来存放就绪的文件描述符。

    epoll_ctl()

    该函数是功能是将被监听的文件描述符添加到epoll句柄,或者从epoll句柄中删除,或者更改文件描述符的监听状态

    将对应的文件描述符添加到红黑树中,或者从红黑树中删除,当将文件描述添加到红黑树时,并给内核中断函数注册一条回调函数,告诉内核,如果该文件描述符就绪,将其添加到就绪链表中

    epoll_wait()

    该函数返回就绪的文件描述和就绪数目的大小

    该函数观察就绪链表中的数据,有数据就返回,没数据就sleep,直到有事件发生或者事件到达

    select 和 epoll对比

    1. select有最大并发数量限制,默认数量是1024个

    2. select 每次调用需要复制全部的fd,文件描述符集合到内核态,并进行线性遍历。
      消耗时间多,且随着文件描述符集合增加,速度越慢,效率延展性差

    3. epoll 没有最大并发数量限制,依赖于系统所能打开的最大文件数目限制

    4. 只有已经就绪的文件才会主动触发回调函数,效率和文件数目大小无关,性能延展性好

    5. epoll中的epoll_ctl contol控制

      1. 可以对文件描述符进行添加和删除操作
      2. 这样就避免了像select那样每次都要复制全部的fd到内核空间
      3. 但是增加,删除和修改也要考虑时间复杂度,明显红黑树就是一个非常好的数据结构。

    总结

    (1)select,poll实现需要自己不断轮询所有fd集合,直到设备就绪,期间可能要睡眠和唤醒多次交替。而epoll其实也需要调用epoll_wait不断轮询就绪链表,期间也可能多次睡眠和唤醒交替,但是它是设备就绪时,调用回调函数,把就绪fd放入就绪链表中,并唤醒在epoll_wait中进入睡眠的进程。虽然都要睡眠和交替,但是select和poll在“醒着”的时候要遍历整个fd集合,而epoll在“醒着”的时候只要判断一下就绪链表是否为空就行了,这节省了大量的CPU时间。这就是回调机制带来的性能提升

    (2)select,poll每次调用都要把fd集合从用户态往内核态拷贝一次,并且要把current往设备等待队列中挂一次,而epoll只要一次拷贝,而且把current往等待队列(红黑树)上挂也只挂一次(在epoll_wait的开始,注意这里的等待队列并不是设备等待队列,只是一个epoll内部定义的等待队列)。这也能节省不少的开销。

  • 相关阅读:
    斩获 offer 的 Java 面试宝典
    golang 运行时死锁排查和检测
    关于图形学中生成三角形库Triangle.Net的下载及简单使用
    树与二叉树堆:二叉树
    Unity Ugui 顶点颜色赋值
    vue的rules验证失效,部分可以部分又失效的原因
    强强联手!三思&华为数字站点数智化隧道联合方案,加速交通智能化
    linux配置jdk
    源码解析篇:ArrayList精讲
    干货 | 解决 App 自动化测试的常见痛点(弹框及首页启动加载完成判断处理)
  • 原文地址:https://blog.csdn.net/weixin_44153921/article/details/126470009