select、poll、epoll(IO多路复用)

news/2024/11/25 21:18:16/

功能

三个模型都是用来判断是否有被监听的socket状态发生改变(读写和异常)

select

首先介绍一下fd_set这个数组,这其实是一个类图,其中每一位表示一个socketfd,哪一位是1表示这一位对应的socket就是被监听的,有三种需要监听的状态,所以就有三个数组,分别是readset,writeset、exceptset,分别监听读写和异常
select原型:

int select(int maxfd, fd_set* readset, fd_set* writeset, fd_set* exceptset, 
const struct timeval* timeout);> 
  1. maxfd表示监听的最大fd(给定了范围)
  2. 三种状态的数组
  3. timeout表示超时时间,当timeout是NULL表示select只有监听到状态发生变化才会结束否则被阻塞,timeout是0表示select非阻塞,立刻返回,timeout>0(数据结构内部有int)表示过一定时间后若还未检测到状态变化就结束
  4. 返回值为状态变化的fd数量,若返回-1表示错误

原理

select采用轮询的方法,遍历fd_set的每一位,检查此socket是否有状态变化,若有变化就把这一位置为1,否则置为0,这样操作之后fd_set表示的意义也从“所有socket的列表”变为了“发生状态变化的socket列表”,接下来只需要遍历这个列表即可处理每一种状态,例如有一个socket有读的需求,则遍历到列表中这个fd时就可以调用read函数,当然由于socketfd意义发生变化,每次select前都需要提前备份一下fd_set,之后每次select后再次select,恢复到备份,这样才能保证每一个监听的fd都被遍历到,还需要注意的时timeout每次也需要重置,当select提前结束,此时timeout会变成剩余的时间,下次select需要重新指定

缺点

  1. 由于select采用轮询的方式,而每次发生状态变化的fd只有几个,更多是非活跃状态的fd,遍历全部花费了太多时间
  2. fd_set内部有最大限制,32位OS最大1024,62位最大2048

poll

poll只优化了select的几个点

  1. poll采用了新的数据结构代替了fd_set,是一个链表,所以最大限制的说法就不复存在了
  2. poll返回值为活跃状态的fd链表,而没有修改监听链表,这样就不需要每次恢复到备份了
    但是poll还是采用轮询的方式,效果依旧很差

epoll

epoll内部采用了红黑树和链表的方式彻底解决了以上问题

  1. 红黑树保存所有带监听的fd,不需要像轮询那样遍历许多非监听的fd
  2. 突破了最大限制
    epoll会把发生事件的fd放到链表中,只需遍历链表即可处理每一个事件

http://www.ppmy.cn/news/47005.html

相关文章

Spark on Yarn(client和cluster模式,spark-shell 和 spark-submit 的区别,WorldCount实现与理解)

文章目录 Spark on Yarn两种模式clientcluster spark-shell 和 spark-submit 的区别的理解spark-shellspark-submit WorldCount实现IDEA本地实现On Yarn 实现WorldCount图解 Spark on Yarn spark on yarn 的两种模式是指 spark 应用程序的 driver 进程(负责控制和协…

java线程小结

线程 1.概念与原理 1.1线程和进程的概念 现在的操作系统是多任务操作系统,而多线程是实现多任务的一种方式 进程:是指内存中运行的应用程序,有自己独立的内存空间,可以独立的运行,进程彼此之间互不干扰,一…

【C++】从C语言入门C++的基础知识

C基础知识 前言1. C关键字2. 命名空间namespace命名空间的创建命名空间的使用命名空间的注意事项 3. C输入&输出4. 缺省参数概念分类全缺省参数半缺省参数 5. 函数重载概念实现C为什么能进行函数重载C和C的相互调用(可以不用看) 6. 引用概念注意事项…

【云原生进阶之容器】第六章容器网络6.4.3--Flannel网络模式

《云原生进阶之容器》专题索引: 第一章Docker核心技术1.1节——Docker综述第一章Docker核心技术1.2节——Linux容器LXC第一章Docker核心技术1.3节——命名空间Namespace第一章Docker核心技术1.4节——chroot技术第一章Docker核心技术1.5.1节——cgroup综述

系统接口幂等性设计探究

前言: 刚开始工作的时候写了一个带UI页面的工具,需要设计登录功能,登录功能也很简单,输入用户名密码点击登录,触发后台查询并比对密码,如果登录成功则返回消息给前端,前端把消息弹出提示一下。…

面向计算机视觉的深度学习:1~5

原文:Deep Learning for Computer Vision 协议:CC BY-NC-SA 4.0 译者:飞龙 本文来自【ApacheCN 深度学习 译文集】,采用译后编辑(MTPE)流程来尽可能提升效率。 不要担心自己的形象,只关心如何实…

MVC和MVVM模式的区别

MVVM 和 MVC 都是软件架构模式,其中 MVVM 表示“Model-View-ViewModel”,而 MVC 表示“Model-View-Controller”。 MVC 模式中,控制器(Controller)充当视图(View)和模型(Model&…

C语言中如何判断大小端字节序?

大小端(Endian)是指多字节整数在内存中存储的方式。在计算机中,一个多字节整数由多个字节组成,而不同的机器和处理器在存储多字节整数时会有两种不同存储方式,分别为大端字节序和小端字节序。 以一个4字节整数0x12345…