高级IO

news2025/3/1 14:58:18

五种IO模型

1、阻塞等待:在内核将数据准备好之前,系统调用会一直等待。所有的套接字,默认都是阻塞方式。

2、非阻塞等待:如果内核没有将数据准备好,系统调用仍然会返回,并且会返回EWUOLDBLOCK或者EAGAIN错误码。

3、信号驱动:内核将数据准备好的时候,使用SIGIO信号通知应用程序进行IO操作。

4、多路转接(多路转接):能够同时等待多个文件句柄的就绪状态。

5、异步IO:由内核在数据拷贝完成时,通知应用程序。(而信号驱动是告诉应用程序什么时候可以开始拷贝数据)。

前四种都属于同步IO,第五种属于异步IO。同步IO和异步IO,区别在于同步IO会参与IO结果的获取的过程。而异步IO则是不会参与IO结果获取的过程,直接拿到最终的IO结果。

IO的本质就是等和拷贝数据。也就是说没有数据的时候,就需要等待数据,当有数据的时候,再将数据拷贝走。而高效的IO,要达到高效,关键在于减少等的比重才能达到效果。在上述的五种IO模型中,多路转接的方式,一次等待多个文件描述符,在某种意义上等的效率更高,也就是说一次等通知多个就绪能够进行拷贝的文件描述符。

I/O多路转接之select

select系统调用是用来让我们的程序监视多个文件描述符的状态变化的; 程序会停在select这里等待,直到被监视的文件描述符有一个或多个发生了状态改变;

函数原型

参数解释:

nfds表示最大文件描述符+1。

readfdswritefdsexceptfds(位图结构)分别需要检测的可读文件描述符集合、可写文件描述符集合和异常文件描述符集合。

timeout表示设置select()的等待时间。(timeout取值(NULL、0、特定时间)

NULL表示阻塞等待,

0则表示仅检测描述符集合的状态,然后立即返回,

特定时间值表示select的等待时间)。

操作fd_set位图结构的接口

函数返回值

执行成功---->则返回文件描述词状态已改变的个数

如果返回0---->代表在描述词状态改变前已超过timeout时间,没有返回

当有错误发生时则---->返回-1,错误原因存于errno,此时参数readfds,writefds, exceptfds和timeout的 值变成不可预测。

select特点

可监控的文件描述符个数取决与sizeof(fd_set)的值. 我这边服务器上sizeof(fd_set)=512,每bit表示一个文件描述符,则我服务器上支持的最大文件描述符是512*8=4096.

将fd加入select监控集的同时,还要再使用一个数据结构array保存放到select监控集中的fd,         一是用于再select 返回后,array作为源数据和fd_set进行FD_ISSET判断。

        二是select返回后会把以前加入的但并无事件发生的fd清空,则每次开始select前都要重新从array取得fd逐一加入(FD_ZERO最先),扫描array的同时取得fd最大值maxfd,用于select的第一个参数。

select缺点

每次调用select, 都需要手动设置fd集合, 从接口使用角度来说也非常不便.

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

每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大

select支持的文件描述符数量太小

I/O多路转接之poll

函数原型

参数解释:

fds是一个poll函数监听的结构列表. 每一个元素中, 包含了三部分内容: 文件描述符, 监听的事件集合, 返回的事件集合.

其中events和revents的取值可以为如下。比如POLLIN或者POLLOUT但是某一位为1的宏,可以设置进events或者内核设置进revents中。

nfds表示fds数组的长度

timeout表示poll函数的超时时间, 单位是毫秒(ms).

返回值

返回值  <  0, 表示出错;

返回值  =  0, 表示poll函数等待超时;

返回值  >  0, 表示poll由于监听的文件描述符就绪而返回

poll的优点

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

        pollfd结构包含了要监视的event和发生的event,不再使用select“参数-值”传递的方式. 接口使用比 select更方便

        poll并没有最大数量限制 (但是数量过大后性能也是会下降,因为需要轮询的检测就绪的事件).

poll的缺点

在监听的文件句柄增多时

和select函数一样,poll返回后,需要轮询pollfd来获取就绪的描述符.

每次调用poll都需要把大量的pollfd结构从用户态拷贝到内核中.

同时连接的大量客户端在一时刻可能只有很少的处于就绪状态, 因此随着监视的描述符数量的增长, 其效率也会线性下降.

I/O多路转接之epoll

函数原型

创建epoll句柄

epoll的函数与select和poll的函数不同,epoll的函数有三个分别独立完成各自功能。

参数size表示所创建的epoll模型,最大能监听文件句柄的数目。

返回值

success -----> return 正数。fail -----> return -1

将要监控的文件描述符进行注册

参数:

        epfd表示我们所创建的epoll模型的文件句柄。

        op表示关心添加的文件句柄的什么行为。用三个宏来表示。

                EPOLL_CTL_ADD :注册新的fd到epfd中;

                EPOLL_CTL_MOD :修改已经注册的fd的监听事件;

                EPOLL_CTL_DEL :从epfd中删除一个fd;

        fd表示我们需要添加关心的文件句柄

        event表示我们关心添加的文件句柄的什么事件。epoll_event结构体如下:

                

                其中events可以是一下宏的集合

返回值:

success -----> return 0。fail -----> return -1

等待文件描述符就绪

参数:

        epfd表示我们所创建的epoll模型的文件句柄。

        events表示系统监听到文件句柄的事件就绪并拷贝至用户的结构体数组

        maxevents表示events数组的大小。

        timeout表示超时时间(毫秒,0会立即返回,-1是永久阻塞)。

返回值:

        success ----> return 就绪的文件描述符的个数。

        超时  ----->  return 0

        fail  ----> return -1

多路转接的工作原理

首先,epoll的使用是一个单进程,因此我们可以通过进程找到对应的epoll句柄。

select和poll的原理:忽略其中的1、2和文件句柄,就单单看3。当外设将数据通过驱动刷新到对应文件句柄中,该文件句柄就就绪了。但是使用者需要轮询遍历3这个队列。

epoll的原理:现在我们需要将上图看作一个整体,epoll模型中存在一个红黑树存放关心的文件句柄,并带有回调函数。当外设将数据通过驱动刷新到对应文件句柄中,该文件句柄就就绪了。然后调用其回调函数,将3中就绪的文件句柄添加到2中的就绪队列中。也就是说,epoll不用再轮询遍历3这个队列了,直接遍历2这个就绪队列就能拿到所有就绪的文件句柄了。

        其次,epoll中维护着红黑树、就绪队列等数据结构,在Linux中都是交由文件管理的。着就是为什么要创建epoll模型,也就是epoll文件句柄了。

        epoll中的三个函数epoll_create、epoll_ctl、epoll_wait,epoll_create函数负责创建句柄,并初始化队列3的大小。epoll_ctl函数负责向红黑树中添加关心的文件句柄,并注册回调函数。epoll_wait函数则是遍历就绪队列2,拿到就绪的文件句柄。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

笔试题目回忆

&#xff08;1&#xff09;给出n,k&#xff0c;n表示数组个数&#xff0c;k表示要剔除的个数&#xff0c;接下来n个数为数组元素&#xff0c;求剔除k个数之后&#xff0c;其他所有数互为倍数&#xff0c;每个数最多剔除一次。 未检测代码&#xff0c;超时。 #include <ios…

第 3 章 栈和队列(单链队列)

1. 背景说明 队列(queue)是一种先进先出(first in first out,缩为 FIFO)的线性表。它只允许在表的一端进行插入&#xff0c;而在另一端删除元素。 2. 示例代码 1&#xff09;status.h /* DataStructure 预定义常量和类型头文件 */#ifndef STATUS_H #define STATUS_H/* 函数结果…

线上问诊:数仓开发(二)

系列文章目录 线上问诊&#xff1a;业务数据采集 线上问诊&#xff1a;数仓数据同步 线上问诊&#xff1a;数仓开发(一) 线上问诊&#xff1a;数仓开发(二) 文章目录 系列文章目录前言一、DWS1.最近1日汇总表1.交易域医院患者性别年龄段粒度问诊最近1日汇总表2.交易域医院患者…

身份识别与鉴权技术调研方案

对称加密算法 对称加密方式又称为私钥加密方式&#xff0c;该方式的加密和解密过程使用同一个密钥&#xff0c;因此该密钥又称为共享密钥。如图2.2所示&#xff0c;在对称加密方式中&#xff0c;发送方使用对称加密算法和共享密钥处理原始数据&#xff0c;得到一个加密后的密文…

vulnhub渗透测试靶场练习2

靶场介绍 靶场名&#xff1a;easy_cloudantivirus 靶场地址&#xff1a;https://www.vulnhub.com/entry/boredhackerblog-cloud-av,453 环境搭建 依旧使用VM VirtualBox搭建靶场&#xff0c;攻击机使用的是VMware中的kali&#xff0c;需要将VMware虚拟机kali和virtualbox靶机…

Web服务器部署上线踩坑流程回顾

5月份时曾部署上线了C的Web服务器&#xff0c;温故而知新&#xff0c;本篇文章梳理总结一下部署流程知识&#xff1b; 最初的解决方案&#xff1a;https://blog.csdn.net/BinBinCome/article/details/129750951?spm1001.2014.3001.5501后来的解决方案&#xff1a;https://blog…

Mysql数据库(3)—架构和日志

Mysql的架构设计 Mysql分为Server层和存储引擎层&#xff1a; Server层 主要包括连接器、查询缓存、分析器、优化器、执行器等&#xff0c;涵盖 MySQL 的大多数核心服务功能&#xff0c;以及所有的内置函数&#xff08;如日期、时间、数学和加密函数等&#xff09;&#xff…

Android逆向学习(一)vscode进行android逆向修改并重新打包

Android逆向学习&#xff08;一&#xff09;vscode进行android逆向修改并重新打包 写在前面 其实我不知道这个文章能不能写下去&#xff0c;其实我已经开了很多坑但是都没填上&#xff0c;现在专利也发出去了&#xff0c;就开始填坑了&#xff0c;本坑的主要内容是关于androi…

回归拟合 | 灰狼算法优化核极限学习机(GWO-KELM)MATLAB实现

这周有粉丝私信想让我出一期GWO-KELM的文章&#xff0c;因此乘着今天休息就更新了(希望不算晚) 作者在前面的文章中介绍了ELM和KELM的原理及其实现&#xff0c;ELM具有训练速度快、复杂度低、克服了传统梯度算法的局部极小、过拟合和学习率的选择不合适等优点&#xff0c;而KEL…

OpenCV(十):图像缩放、翻转、拼接的介绍与使用

目录 &#xff08;1&#xff09;图像缩放&#xff1a;resize() &#xff08;2&#xff09;图像翻转&#xff1a; flip() &#xff08;3&#xff09;图像拼接&#xff1a;hconcat() 和vconcat() &#xff08;1&#xff09;图像缩放&#xff1a;resize() 使用 cv2.resize() 函…

React笔记(三)类组件(1)

一、组件的概念 使用组件方式进行编程&#xff0c;可以提高开发效率&#xff0c;提高组件的复用性、提高代码的可维护性和可扩展性 React定义组件的方式有两种 类组件&#xff1a;React16.8版本之前几乎React使用都是类组件 函数组件:React16.8之后&#xff0c;函数式组件使…

北京APP外包开发团队人员构成

下面是一个标准的APP开发团队构成&#xff0c;但具体的人员规模和角色可能会根据项目的规模和需求进行调整。例如&#xff0c;一些小型项目或初创公司可能将一些角色合并&#xff0c;或者聘请外包团队来完成部分工作。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公…

使用rabbitmq进行支付之后的消息通知

订单服务完成支付后将支付结果发给每一个与订单服务对接的微服务&#xff0c;订单服务将消息发给交换机&#xff0c;由交换机广播消息&#xff0c;每个订阅消息的微服务都可以接收到支付结果. 微服务收到支付结果根据订单的类型去更新自己的业务数据。 相关技术方案 使用消息…

【LeetCode】85.最大矩形

题目 给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵&#xff0c;找出只包含 1 的最大矩形&#xff0c;并返回其面积。 示例 1&#xff1a; 输入&#xff1a;matrix [["1","0","1","0","0"],["1&quo…

11. 微积分 - 偏导数方向导数

文章目录 偏导数方向导数方向余弦投影继续讲方向导数Hi, 大家好。我是茶桁。 我们上节课学习了链式法则,本节课,我们要学习「偏导数」和「方向导数」。 偏导数 偏导数在导论课里面也提到过。偏导数针对多元函数去讲的。 多元函数是什么,我们拿个例子来看: 多元函数: y…

springboot配置ym管理各种日记(log)

1&#xff1a;yml配置mybatis_plus默认日记框架 mybatis-plus:#这个作用是扫描xml文件生效可以和mapper接口文件使用&#xff0c;#如果不加这个,就无法使用xml里面的sql语句#启动类加了MapperScan是扫描指定包下mapper接口生效&#xff0c;如果不用MapperScan可以在每一个mapp…

2023.9.2 关于 JVM 垃圾回收机制(GC)

目录 为什么要有垃圾回收机制? STW&#xff08;Stop The World&#xff09;问题 垃圾回收机制主要回收哪个内存区域? 垃圾对象判断算法 引用计数算法 可达性分析算法 垃圾对象回收算法 标记清除算法 复制算法 标记整理算法 分代算法 为什么要有垃圾回收机制? 自动…

thinkphp中使用Elasticsearch 7.0进行多表的搜索

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、thinkphp中使用Elasticsearch 7.0进行多表的搜索二、使用步骤1.引入库2.读入数据 总结 前言 提示&#xff1a;thinkphp中使用Elasticsearch 7.0进行多表的…

stable diffusion实践操作-批次出图

系列文章目录 stable diffusion实践操作 文章目录 系列文章目录前言一、批次出图介绍1.1 webUI设置1.2 参数介绍 二、批次出图使用2.1 如何设置2.1 效果展示 总结 前言 本章主要介绍SD批次出图。 想要一次产生多张图片的时候使用。 一、批次出图介绍 1.1 webUI设置 1.2 参数…

[管理与领导-65]:IT基层管理者 - 辅助技能 - 4- 乌卡时代(VUCA )

前言&#xff1a; 大多数IT人&#xff0c;很勤奋&#xff0c;但都没有职业规划&#xff0c;被工作驱动着前行&#xff0c;然而&#xff0c;作为管理者&#xff0c;你就不能没有职业规划思维&#xff0c;因为你代表一个团队&#xff0c;你的思维决定了一个团队的思维。本文探讨…