五种IO模型以及select多路转接IO模型

news/2024/4/23 14:17:48/文章来源:https://blog.csdn.net/flyingcloud6/article/details/129109180

目录

一、典型IO模型

 1.1 阻塞IO

1.2 非阻塞IO

1.3 信号驱动I0

1.4 IO多路转接

 1.5 异步IO

多路转接的作用和意义

二、多路转接IO模型(select)

2.1 接口

 2.2 接口当中的事件集合: fd_set

2.2  select使用事件集合(位图)的方式

2.2.1 接口

2.3 select使用方式:

2.4 select的返回值:(有点反人类)

2.5 select的测试代码:

三、 用select来实现单个线程接收多个客户端


一、典型IO模型

 1.1 阻塞IO

在内核将数据准备好之前,系统调用会一直等待,直到数据的到来,拷贝完成数据后,IO调用才会返回

  • 1.2 非阻塞IO

  • 如果内核还未将数据准备好,系统调用仍然会直接返回,并且返回EWOULDBLOCK错误码。非阻塞IO的返回,需要判断系统调用函数的返回值,来判断当前函数是否将IO功能完成。
  • 1.没完成:一般会搭配循环继续调用(IO功能没有完成),但是这样对于CPU的资源也是巨大的浪费。
  • 2.完成了:内核将数据准备好了,拷贝回来了(IO功能完成)

  • 1.3 信号驱动I0

  • (就像是鱼竿上面绑了个铃铛)
  • 内核将数据准备好的时候,使用SIGIO信号通知应用程序进行I0操作。这里例如我们对于僵尸进程(僵尸进程就是子进程先于父进程退出,子进程的退出信息没有人回收)的处理可以配合信号当子进程退出的时候我们自定义信号的处理方式。调用wait函数来回收子进程

  • 1.4 IO多路转接

  • 我们首先来看一个场景

上面那种无脑创建进程、线程的方法是不能处理大量客户端的情况的。那怎么来解决呢?

需要使用多路转接

多路转接IO模型可以帮我们同时监控多个文件描述符

 有了多路转接,就可以不用无脑的创建线程或者进程了

就好比钓鱼的时候雇人去钓鱼,如果说哪个鱼竿上鱼了,让他别动,我们去享受把鱼拽上来的快感

  •  1.5 异步IO

  • 由内核在数据拷贝完成时,通知应用程序(而信号驱动是告诉应用程序何时可以开始拷贝数据)。好比说钓鱼,信号IO就是相当于鱼竿上面帮了一个铃铛,铃铛响了的时候通知你来将鱼竿收起然后钓鱼,而异步IO则是帮你钓鱼,就是帮你找了一个人当他调好了鱼之后来通知你取鱼

 同步IO和异步IO的最大区别就是:

异步IO啥事也不管,只是告诉你我要做这件事情,接下来这件事情由你来做(你怎么多久是你的事情),做完你再告诉我

多路转接的作用和意义

1、作用:IO多路转接可以帮助我们同时等待多个文件描述符的就绪状态,多路转接IO模型可以帮助我们同时监控多个文件描述符

 2、多路转接IO模型,就是程序高并发的基础

高并发:  程序可以处理大量的客户端请求

3、扩展:一个好的程序,需要考量高并发,也需要考量高可用

高可用:就说不管程序遇到什么糟糕场景,都是可以使用的,比如程序挂掉了(备份进程)(守护进程)

二、多路转接IO模型(select)

  • 2.1 接口

  • int select(int nfds, fd_set  *readfds, fd_set  *writefds,fd_set  *exceptfds, struct timeval  *timeout);

nfds :取值为最大文件描述符的数值+1,作用是:控制select的轮询监控范围。

  • fd_set   :  事件集合
  • readfds :    读事件集合
  • writefds:  写事件集合
  • exceptfds:异常事件集合

timeout  :  表示工作方式

  • 阻塞方式 : NULL
  • 非阻塞     : 0
  • 带有超时时间的监控:传递struct  timeval 这样的结构体对象

  • 返回值:
  • 成功:返回就绪文件描述符的个数
  • 失败:返回-1,并且设置了errno,程序员就可以通过perror这个函数查看失败原因

 2.2 接口当中的事件集合: fd_set

 第一印象:

        fd_set :  是一个结构体,结构体当中有一个数组,名字为fds_bits

探究:

  • 1.   数据的元素类型是什么?
  • 2.数据的元素个数为多少?

 我们可以发现,数组的大小只有16个,这就很奇怪了,如果一个元素存放一个文件描述符数值,那最多也才16个,这肯定是不对的,太少了,一个进程随随便便就会有很多个文件描述符。

那到底是什么回事呢?

事件集合的使用方式并不是按照数组的方式来使用的,而是按照比特位(位图)的方式使用的

2.2  select使用事件集合(位图)的方式

2.2.1 接口

  • void FD_CLR(int fd,fd_set *set) ;
    • 作用:将fd从事件集合set当中去除掉,本质就是将fd对应的比特位置为0
  • int FD_ISSET(int fd,fd_set *set) ;
    • 作用:判断fd文件描述符,是否在set集合当中,本质是判断fd对应的比特位是否为0
    • 返回值:
    • 0:表示fd不在set当中
    • 1:表示fd在set当中
  • void FD_SET(int fd,fd_set *set) ;
    • 作用:设置fd文件描述符到set事件集合当中,本质是将fd对应的比特位设置为1
  • void FD_ZERO(fd_set *set) ;
    • 作用:清空事件集合.本质是将set当中所有的比特位都置为0

例子:

  • 2.3 select使用方式:

  • 1..select共有三个事件集合:读事件集合,写事件集合,异常事件集合。
  • 2.当需要关注某个文件描述符的某个事件,则将来个文件描述符添加到对应的事件集合当中。例如:关注(0号文件描述符的读事件,则将0号文件描述符添加到读事件集合当中readfds。
  • 3.如果不关注某种事件,则给select传递参数的时候,传递NULL。

  • 2.4 select的返回值:(有点反人类)

  • 1.返回值为就绪的文件描述符的个数
  • 2.就绪的文件描述符存储在事件集合当中返回给调用者

但是:没有就绪的文件描述符呢?也放在事件集合当中吗?

肯定不会,因为select监控成功完事件集合之后,还是要判断哪些文件描述符就绪了,为了能够判断出来,就需要将未就绪的除掉

 所以,如果select监控成功之后,再次需要监控时,需要将上一次未就绪的文件描述符给他放到事件集合当中去

  • 2.5 select的测试代码:

代码:

 

 

 之前是阻塞在scanf的等待读过程,我们看看用到了select进行监控,这个进程阻塞在哪里:

  • 三、 用select来实现单个线程接收多个客户端

  • 我们知道如果没有多路转接io的话那么就要用多线程来处理接收多个客户端连接服务端。那么这里我们就可以实现用一个线程来实现接收多个客户端的连接。

改造前:

        accept 放到while 循环的外面,这个进程一辈子只能接收一个客户端的连接

        accept 放到while 循环的外面,这个进程一辈子只能和客户端联系一次(但是可以和多个客户端发送数据)  

改造后:

        思路: select 帮助我们监控listen_sockfd(一个),new_sockfd(多个)

                   当select监控成功之后,我们针对不同的文件描述符做出不同的操作

                   listen_sockfd (读事件) :accept

                   new_sockfd (读事件):recv     

服务端:

客服端:

 运行一下观察结果:

 可以看到,一个线程就能处理多态客户端,属实是神奇!!!

四、select的优缺点

4.1优点:

4.2缺点

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_73915.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

174万亿采购,奔向数字化

采购不单纯发生在外部,更发生在内部,只有两者同时进行,才能完成采购中心从成本到利润中心角色的转变。 作者|斗斗 编辑|皮爷 出品|产业家 数字化,让很多企业业务流程发生了质变。 《2022数字化采购发展报告》显示&#x…

破解票房之谜:为何高票房电影绕不过“猫眼们”?

如此火爆的春节档很多,如此毁誉参半的春节档鲜有。2023开年,集齐张艺谋、沈腾的《满江红》,以及有票房前作打底的《流浪地球2》接连两部春节档电影票房进入前十,为有些颓靡的中国电影市场注入了一针“强心剂”。与票房同样热闹起来…

无重叠区间-力扣435-java贪心策略

一、题目描述给定一个区间的集合 intervals ,其中 intervals[i] [starti, endi] 。返回 需要移除区间的最小数量,使剩余区间互不重叠 。示例 1:输入: intervals [[1,2],[2,3],[3,4],[1,3]]输出: 1解释: 移除 [1,3] 后,剩下的区间没有重叠。…

【爬虫】2.2 BeautifulSoup 装载HTML文档

HTML文档结点的查找工具很多,其中 BeautifulSoup 是功能强大且十分流行的查找工具之一。1. BeautifulSoup 的安装安装:pip install bs4导包:from bs4 import BeautifulSoup2. BeautifulSoup 装载HTML文档如果 doc 是一个 HTML 文档&#xff0…

深度学习训练营之yolov5 官方代码调用以及-requirements.txt下载当中遇到的问题

深度学习训练营之yolov5 官方代码调用原文链接内容总结环境介绍前置工作简单介绍yolov5下载源码yolov5的下载遇到问题问题解析问题处理创建虚拟环境下载当中遇到的问题代码运行视频检测参考内容原文链接 🍨 本文为🔗365天深度学习训练营 中的学习记录博客…

gazebo仿真环境中添加robotiq 2f 140的gripper_controller控制器

gazebo仿真环境中添加robotiq 2f 140的gripper_controller控制器 搭建环境: ubuntu: 20.04 ros: Nonetic sensor: robotiq_ft300 gripper: robotiq_2f_140_gripper UR: UR3 reasense: D435i 通过下面几篇博客配置好了ur3、力传感器、robotiq夹爪、rea…

18523-47-2,3-Azidopropionic Acid,叠氮基丙酸,可以与炔烃发生点击化学反应

【中文名称】3-叠氮基丙酸【英文名称】 3-Azidopropionic Acid,3-Azidopropionic COOH【结 构 式】【CAS】18523-47-2【分子式】C3H5N3O2【分子量】115.09【纯度标准】95%【包装规格】1g,5g,10g【是否接受定制】可进行定制,定制时…

java原理4:java的io网络模型

文章目录1:基础概念1:同步和异步2:阻塞和非阻塞2.1:阻塞IO2.2:非阻塞io2.3:io复用3:同步/异步和阻塞/非阻塞3.1:同步非阻塞NIO4: redis为什么速度快Java 网络IO模型简介1&#xff1a…

Tapdata 和 Databend 数仓数据同步实战

作者:韩山杰https://github.com/hantmacDatabend Cloud 研发工程师基础架构在云计算时代也发生着翻天地覆的变化,对于业务的支持变成了如何能利用好云资源实现降本增效,同时更好的支撑业务也成为新时代技术人员的挑战。 本篇文章通过&#xf…

删除MySQL表中的重复数据?

前言 一般我们将数据存储在MySQL数据库中,它允许我们存储重复的数据。但是往往重复的数据是作废的、没有用的数据,那么通常我们会使用数据库的唯一索引 unique 键作为限制。问题来了啊,我还没有创建唯一索引捏,数据就重复了&…

jianzhiOffer第二版难重点记录

04. 二维数组中的查找https://leetcode.cn/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/ 思路:可以每层用以恶搞二分查找,优化思路:从左下角出发直接用二分。 ​​​​​​07. 重建二叉树https://leetcode.cn/problems/zhong-jian-er-cha…

springboot+vue.js高校大学生选课成绩管理系统javaweb

本课题要求实现一套学生成绩管理系统,系统主要包括管理员,学生和教师三大模块 (a) 管理员;管理员进入系统主要功能包括首页,个人中心,教师管理,学生管理,公告信息管理,课程类型管理&…

Android自定义View实现横向的双水波纹进度条

效果图:网上垂直的水波纹进度条很多,但横向的很少,将垂直的水波纹改为水平的还遇到了些麻烦,现在完善后发布出来,希望遇到的人少躺点坑。思路分析整体效果可分为三个,绘制圆角背景和圆角矩形,绘…

Linux学习(7.5)linux目录配置与重点回顾

鸟哥的 Linux 私房菜 -- Linux 的文件权限与目录配置 (vbird.org) 怎么记啊,直接点进去看吧 目录 Linux目录配置的依据--FHS 绝对路径与相对路径 重点回顾 以下内容转载自鸟哥的Linux私房菜 Linux目录配置的依据--FHS 是希望让使用者可以了解到已安装软件通常…

16、变量、流程控制与游标

文章目录1 变量1.1 系统变量1.1.1 系统变量分类1.1.2 查看系统变量1.2 用户变量1.2.1 用户变量分类1.2.2 会话用户变量1.2.3 局部变量1.2.4 对比会话用户变量与局部变量2 定义条件与处理程序2.1 案例分析2.2 定义条件2.3 定义处理程序2.4 案例解决3 流程控制3.1 分支结构之 IF3…

嵌入式系统硬件设计与实践(学习方法)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 刚读书的时候,对什么是嵌入式,其实并不太清楚。等到自己知道的时候,已经毕业很多年了。另外对于计算机毕业的学…

Python近红外光谱分析与机器学习、深度学习方法融合实践技术

、 第一n入门基础【理论讲解与案 1、Python环境搭建( 下载、安装与版本选择)。 2、如何选择Python编辑器?(IDLE、Notepad、PyCharm、Jupyter…) 3、Python基础(数据类型和变量、字符串和编码、list和tu…

每日学术速递2.24

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.LG 1.BUAA_BIGSCity: Spatial-Temporal Graph Neural Network for Wind Power Forecasting in Baidu KDD CUP 2022 标题:BUAA_BIGSCity:百度KDD CUP 2022风电预测…

新C++(10):Map\Set的封装

"湖人总冠军"一、Map\Set的介绍Set是C标准库中的一种关联容器。所谓关联容器就是通过键(key)来读取和修改元素。与map关联容器不同,它只是单纯键的集合。取自这里Map是STL 的一个关联容器,它提供一对一(其中…

《分布式技术原理与算法解析》学习笔记Day21

分布式数据存储三要素 什么是分布式数据存储系统? 分布式存储系统的核心逻辑,就是将用户需要存储的数据根据某种规则存储到不同的机器上,当用户想要获取指定数据时,再按照规则到存储数据的机器中获取。 分布式存储系统的三要素…