当前位置: 首页 > news >正文

重新认识IO以及五种IO模型(理论认识)

目录

一、重新认识IO

1、读取数据

2、写入数据

二、认识五种IO模型

1、场景一:干等式钓鱼

2、场景二:频繁检测式钓鱼

3、场景三:提醒式钓鱼

4、场景四:批量式钓鱼

5、场景五:代理式钓鱼

三、什么时候结束等待??


最早在学习文件系统的时候,对IO的初步认识是将数据写入到文件以及从文件读取数据。但是学习TCP/IP时了解到,传输层属于内核区,存在接收/发送缓冲区。

因此我们对IO有了一个新的认识,以TCP/IP模型为例,IO过程其实是一个拷贝的过程,读取就是将接收缓冲区里的数据拷贝到应用层,写入就是将应用层的数据拷贝到发送缓冲区。

一、重新认识IO

实际上的IO并不是像最开始那么简单,还需要在上述结论的基础上润润色。

1、读取数据

前面说到,读取数据本质是将接收缓冲区的数据拷贝到用户层,但是如果接收缓冲区里没有数据呢?此时上层就需要先等待接收缓冲区里的数据准备就绪了,再读取数据。

五种IO模型其实就是采用不同的等待方式来等待数据就绪

2、写入数据

写入数据也是同理,写入数据本质是将应用层的数据拷贝到发送缓冲区。如果发送缓冲区已经满了,此时上层也需要等待发送缓冲区里的剩余空间准备就绪了,然后再拷贝数据到发送缓冲区。

五种IO模型无论是读取还是写入,都有两个过程 等待拷贝。=》 IO过程 = 等待 + 拷贝 

二、认识五种IO模型

与IO模型相关的无非就两个话题:改变等待的方式、减少等待时间的比重。改变等待的方式可以直接或者间接影响等待时间的比重;减少等待时间相对于IO过程所花时间的比重 衡量了一个IO过程是否高效

下面就以五种钓鱼的场景来认识这五种模型。

1、场景一:干等式钓鱼

张三钓鱼的方式很简单,把饵抛下去以后,就死死盯着浮标,一旦浮标动了,就把鱼拉上来。

这种方式其实就是阻塞模型,read接口函数就是典型的阻塞模型,每次只能等待一个文件描述符,在接收缓冲区有足够的数据之前,会一直阻塞等待,此时的read函数也不会有返回值。

2、场景二:频繁检测式钓鱼

李四的钓鱼方式就稍微好一点,把饵抛下去以后,就坐在一边看看书,每隔10s抬头看看浮标有没有动静,如果有动静了就把鱼钓上来。

这种方式就是非阻塞模型,以读数据为例,其实就是通过while循环不断进入检测数据是否就绪,如果没有就绪则继续循环检测;如果数据就绪,就把数据读取到上层。一般不建议使用这种方式,不断检测就意味着要从用户态切换到内核态,然后再切换回来,这对CPU来说是较大的浪费。

3、场景三:提醒式钓鱼

王五把饵抛下去以后,在鱼竿上挂了一个铃铛,然后就坐在一边看书不管不顾,当铃铛响了的时候,就把鱼钓上来。

这种方式就是信号驱动模型。每当内核有数据就绪的时候,主动通知上层来取,发送的信号为第29号信号 SIGIO。这种方式并非最佳方案,有的时候,即便数据就绪了也不一定会发送这个信号,因为接收缓冲区存在水位线的概念,只有当数据达到一定量的时候,才会让上层来取。

4、场景四:批量式钓鱼

赵六有自己的想法,他钓鱼的时候,把20个鱼竿插在了岸边,然后就在岸边轮询,一个一个的看过去,如果有哪个鱼竿的浮标动了,就把鱼钓上来。

这种方式就是多路转接模型。类似于阻塞模型的批量版,但是最关键的是,一次可以等待多个文件描述符,只要有一个文件描述符变为可读状态,就把数据读取到上层。

5、场景五:代理式钓鱼

田七是个老板,不想钓鱼,只想吃鱼,于是就让他的司机去河边钓鱼,同时给他一个空桶,让司机把桶装满了再打电话通知他。

这种方式就是异步IO模型。此时上层就没有参与到IO这个过程,只是在调用接口函数的时候,告诉内核数据准备就绪以后直接放到某个位置。上层只关心数据什么时候准备好,完全不关心数据的获取过程。

三、什么时候结束等待??

结束等待的时间是 读事件就绪 或者 等事件就绪。

读事件就绪,其实是当接收缓冲区有了足够的数据以后,再让上层去读。缓冲区里有水位线的概念,没有超过水位线,说明数据量较少,此时不会通知上层来取,因为读取一次有成本,需要从用户态切换到内核态,然后再切换回去,频繁切换状态的成本很高。

写事件就绪,其实是当缓冲区里有足够的空间来存放上层拷贝的数据时,再让上层拷贝到缓冲区。

补充:学习TCP协议的时候有个psh标记位,其实就是在告诉对方OS“不要去管什么水位线了,赶紧让上层把数据取走吧”

相关文章:

  • leetcode: 647. 回文子串
  • SQL语言概述与SQL语言的数据定义
  • NIO知识总结三
  • c语言分层理解(动态内存分配)
  • 【Vite基础】001-使用 Vite 创建 vue3 项目
  • 微服务项目:尚融宝(58)(核心业务流程:提现和还款(1))
  • 限时折扣助力知识店铺销量暴涨
  • 信息学一本通 1213:八皇后问题
  • 网络安全——文件包含漏洞
  • 制造型企业的数字化转型离不开 MES 系统
  • Unity使用新输入系统InputSystem制作飞机大战Demo(对象池设计模式及应用)
  • Oracle-WeiTo基础
  • GTC2021小结
  • RocketMQ——RocketMQ搭建及问题解决
  • 0基础和我学前端---(1)走进前端世界
  • 网络传输文件的问题
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • 0x05 Python数据分析,Anaconda八斩刀
  • Idea+maven+scala构建包并在spark on yarn 运行
  • js递归,无限分级树形折叠菜单
  • laravel5.5 视图共享数据
  • Redash本地开发环境搭建
  • vue数据传递--我有特殊的实现技巧
  • 创建一个Struts2项目maven 方式
  • 分享一份非常强势的Android面试题
  • 给新手的新浪微博 SDK 集成教程【一】
  • 理清楚Vue的结构
  • 使用parted解决大于2T的磁盘分区
  • 数据仓库的几种建模方法
  • 远离DoS攻击 Windows Server 2016发布DNS政策
  • 如何用纯 CSS 创作一个货车 loader
  • 选择阿里云数据库HBase版十大理由
  • ​io --- 处理流的核心工具​
  • ​虚拟化系列介绍(十)
  • #!/usr/bin/python与#!/usr/bin/env python的区别
  • #ifdef 的技巧用法
  • #我与Java虚拟机的故事#连载03:面试过的百度,滴滴,快手都问了这些问题
  • (二十三)Flask之高频面试点
  • (附源码)基于SSM多源异构数据关联技术构建智能校园-计算机毕设 64366
  • (三十五)大数据实战——Superset可视化平台搭建
  • (原創) 如何將struct塞進vector? (C/C++) (STL)
  • (转)visual stdio 书签功能介绍
  • (转)重识new
  • .NET BackgroundWorker
  • .net core 微服务_.NET Core 3.0中用 Code-First 方式创建 gRPC 服务与客户端
  • .net 按比例显示图片的缩略图
  • .NET项目中存在多个web.config文件时的加载顺序
  • @Transactional 竟也能解决分布式事务?
  • [ HTML + CSS + Javascript ] 复盘尝试制作 2048 小游戏时遇到的问题
  • [2]十道算法题【Java实现】
  • [④ADRV902x]: Digital Filter Configuration(发射端)
  • [ANT] 项目中应用ANT
  • [HUBUCTF 2022 新生赛]
  • [IE9] IE9 Beta崩溃问题解决方案
  • [java/jdbc]插入数据时获取自增长主键的值