IO多路复用之Select、Poll、Epoll

发表于:2021-7-12 09:58

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:王策    来源:51Testing软件测试网原创

#
开发
  I/O多路复用就是通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知应用程序进行相应的读写操作。

  1.select
  基本原理:select 函数监视的文件描述符分3类,分别是writefds、readfds、和exceptfds。调用后select函数会阻塞,直到有描述符就绪(有数据 可读、可写、或者有except),或者超时(timeout指定等待时间,如果立即返回设为null即可),函数返回。当select函数返回后,可以通过遍历fdset,来找到就绪的描述符。
  被监控的fd在select()后会发生改变,所以在下一次进入select()之前要重新初始化fd。
  优点:良好的跨平台特性。
  缺点:单个进程在Linux下默认最大连接数是1024(可以改);对socket扫描时采用轮询,效率低;需要维护fd_set(long型数组),这样会使得用户空间和内核空间在传递该结构时复制开销大,内核遍历开销也大。

  2.poll
  本质上和select没有什么区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态,如果设备就绪则在设备等待队列中加入一项并继续遍历,如果遍历完所有fd后没有发现就绪设备,则挂起当前进程,直到设备就绪或者主动超时,被唤醒后它又要再次遍历fd。这个过程经历了多次无谓的遍历。不同之处在于,它基于链表实现,没有最大连接数限制,但仍受限于硬限制,相对于epoll是 “水平触发”, 只需要初始化一次,关心的事件和发生的事件进行了分离。

  3.epoll:双向链表+红黑树
  epoll支持水平触发和边缘触发,最大的特点在于边缘触发,它只告诉进程哪些fd刚刚变为就绪态,并且只会通知一次。还有一个特点是,epoll使用“事件”的就绪通知方式,通过epoll_ctl注册fd,一旦该fd就绪,内核就会采用类似callback的回调机制来激活该fd,epoll_wait便可以收到通知,内核空间和用户空间共享一块内存实现。
  优点:
  (1)没有最大并发连接的限制,能打开的fd的上限远大于1024(1G的内存上能监听约10万个端口)。
  (2)效率提升,不是轮询的方式,不会随着fd数目的增加效率下降。只有活跃可用的fd才会调用callback函数;即epoll最大的优点就在于它只管你“活跃”的连接,而跟连接总数无关,因此在实际的网络环境中,epoll的效率就会远远高于select和poll。
  (3)内存拷贝,利用mmap()文件映射内存加速与内核空间的消息传递;即epoll使用mmap减少复制开销。

      版权声明:本文出自51Testing会员投稿,51Testing软件测试网及相关内容提供者拥有内容的全部版权,未经明确的书面许可,任何人或单位不得对本网站内容复制、转载或进行镜像,否则将追究法律责任。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号