首页 > 其他分享 >I/O多路复用(select poll epoll)

I/O多路复用(select poll epoll)

时间:2023-06-08 16:25:55浏览次数:37  
标签:epoll 描述符 fd 内核 poll select

select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的。而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间

select

调用后select函数会阻塞,直到有描述符就绪(有数据 可读、可写、或者有except),或者超时(timeout指定等待时间,如果立即返回设为null即可),函数返回。

当select函数返回后,可以 通过遍历fdset,来找到就绪的描述符

优点:

  1. select目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点

缺点:

  1. 单个进程能够监视的文件描述符的数量存在最大限制,它由FD_SETSIZE设置,默认值是1024。 可以通过修改宏定义甚至重新编译内核的方式提升这一限制,但 是这样也会造成效率的降低。

  2. fd集合在内核被置位过,与传入的fd集合不同,不可重用。 重复进行FD_ZERO(&rset); FD_SET(fds[i],&rset);操作

  3. 每次调⽤用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大。

  4. 同时每次调用select都需要在内核遍历传递进来的所有fd标志位,O(n)的时间复杂度,这个开销在fd很多时也很大。

poll

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

优点:

  1. poll用pollfd数组代替了bitmap,没有最大数量限制。(解决select缺点1)

  2. 利用结构体pollfd,每次置位revents字段,每次只需恢复revents即可。pollfd可重用。(解决select缺点2)

缺点:

  1. 每次调⽤用poll,都需要把pollfd数组从用户态拷贝到内核态,这个开销在fd很多时会很大。(同select缺点3)

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

epoll

epoll更加灵活,没有描述符限制epoll使用一个文件描述符管理多个描述符,将用户关系的文件描述符的事件存放到内核的一个事件表中,这样在用户空间和内核空间的copy只需一次。

每一个epoll对象都有一个独立的eventpoll结构体,用于存放通过epoll_ctl方法向epoll对象中添加进来的事件。这些事件都会挂载在红黑树中,如此,重复添加的事件就可以通过红黑树而高效的识别出来(红黑树的插入时间效率是lgn,其中n为树的高度)。

而所有添加到epoll中的事件都会与设备(网卡)驱动程序建立回调关系,也就是说,当相应的事件发生时会调用这个回调方法。这个回调方法在内核中叫ep_poll_callback,它会将发生的事件添加到rdlist双链表中。

当调用epoll_wait检查是否有事件发生时,只需要检查eventpoll对象中的rdlist双链表中是否有epitem元素即可。如果rdlist不为空,则把发生的事件复制到用户态,同时将事件数量返回给用户 。

优点:

  1. 监视的描述符数量不受限制

  2. epoll是内核空间用一个 红黑树维护所有的fd,epoll_wait 通过回调函数内核会将 I/O 准备好的描述符加入到一个链表中管理,只把就绪的fd用链表复制到用户空间。

  3. IO的效率不会随着监视fd的数量的增长而下降。epoll不同于select和poll轮询的方式,而是通过每个fd定义的回调函数来实现的

标签:epoll,描述符,fd,内核,poll,select
From: https://www.cnblogs.com/yogayao/p/17466805.html

相关文章

  • select2多选下拉框
    <!DOCTYPEhtml><html><head><metacharset="UTF-8"><title></title><linkrel="stylesheet"type="text/css"href="https://cdnjs.cloudflare.com/ajax/libs/selec......
  • 42 最佳实践-性能最佳实践-halt-polling
    42最佳实践-性能最佳实践-halt-polling42.1概述在计算资源充足的情况下,为使虚拟机获得接近物理机的性能,可以使用halt-polling特性。没有使用halt-polling特性时,当vCPU空闲退出后,主机会把CPU资源分配给其他进程使用。当主机开启halt-polling特性时,虚拟机vCPU处于空闲时会polling......
  • select 多选回显的时候input高度问题
    select多选回显的时候input高度没撑开内容超出setTimeout(function(){if(document.querySelector('.el-cascader__tags')){document.querySelector('#el-cascader.el-input__inner').style.setProperty('height',`${document......
  • 通过redis学网络(1)-用go基于epoll实现最简单网络通信框架
    本系列主要是为了对redis的网络模型进行学习,我会用golang实现一个reactor网络模型,并实现对redis协议的解析。系列源码已经上传githubhttps://github.com/HobbyBear/tinyredis/tree/chapter1redis的网络模型是基于epoll实现的,所以这一节让我们先基于epoll,实现一个最简单的服......
  • docker: Error response from daemon: could not select device driver "" with capab
    docker19之后的版本1.nanonvidia.shsudocurl-s-Lhttps://nvidia.github.io/nvidia-container-runtime/gpgkey|\ sudoapt-keyadd-distribution=$(./etc/os-release;echo$ID$VERSION_ID)sudocurl-s-Lhttps://nvidia.github.io/nvidia-container-runtime/$dist......
  • 浅谈二次剩余与Cipolla算法
    Preface数论菜鸡来补一手知识黑洞,二次剩余以前OI时期还真一点没了解过,所以先写个板题先(虽然当初想着反正到时候有数学巨佬队友带我飞,但多学一点总是好的)二次剩余又俗称模意义下开根,用于求解\(x^2\equivn\pmodp\)这样的方程但注意一般情况下我们只讨论当\(p\)为奇素数时的情......
  • mysql select into outfile 语法 乱码问题
    一个常见的问题,mysql导出csv格式的语法,已经乱码问题:由于数据库一般默认的是UTF-8格式的字符集,而execl默认的是gbk格式的字符集,这里有两种方法解决乱码:方法一:先转出.txt格式的文件,然后选择用excel打开时,提示选择哪种编码打开,选择gbk即可select*frommobile_order_regionwhere......
  • MySQL server version for the right syntax to use near 'OPTION SQL_SELECT_LIMIT=D
    hive删除表时报错如下:hive>droptableaaa;FAILED:ExecutionError,returncode1fromorg.apache.hadoop.hive.ql.exec.DDLTask.MetaException(message:javax.jdo.JDODataStoreException:YouhaveanerrorinyourSQLsyntax;checkthemanualthatcorrespondstoyou......
  • mysql数据库的锁-select for update
    乐观锁与悲观锁乐观锁和悲观锁只是两个加锁的思路,其实现方式多种多样。以下举几个在mysql数据库中的例子。  对于一次的数据修改,我们可以大概将其分为三步:获取数据修改数据提交修改乐观锁假设A、B两个角色对数据进行修改:乐观锁对数据保持一个乐观态度(大概率......
  • golang中for select时,如果channel关闭会怎么样?
    首先,如果对于一个已经关闭的channel来说,如果此时channel里还有值,则会正确读到channel里的值,且返回的第二个bool值为true;如果关闭前,channel里的值已经被读完,则最后返回的则是channel的零值;那么针对该问题,我们通过代码来验证一下:packagemainimport( "fmt" "time")constt......