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

Linux——五种IO模型

目录

一、I/O的理解

二、五种IO模型

1.阻塞式IO

2.非阻塞式IO

3.信号驱动IO

4.多路复用IO

5.异步IO 


一、I/O的理解

I/O的本质就是输入输出,C语言的stdio,C++的iostream,添加了这两个库,我们才能够进行printf、scanf、cin、cout。

在I/O中,我们大部分时间是在等,比如你调用了scanf(),当前进程就在等待你的输入,你输入完毕后,把输入数据拷贝到内存中,才会继续执行。因此,I/O = 等 + 拷贝。拷贝的效率是硬件决定的,但是等待的时间,是可以由程序来优化的。单位时间内,减少了等的比重,这也就提高了I/O效率。

在网络中,我们经常需要去recv和send,recv是在等待对方发送消息,我来接受,如果此时对方还没有发送消息,我们就会在recv这里阻塞;send则是我发送消息,对方接受消息,当对方的接受缓冲区满了,也会造成阻塞,直到对方接收缓冲区有空间了,才可以发送过去。

如果现在我可以去干自己的事情,等我收到的对方通知(他的条件满足),我们再去调用recv或者send函数,这样就大大提高了效率

二、五种IO模型

为了理解五种IO模型,我们来看个钓鱼的例子,钓鱼 = 等 + 钓 ,这里可以把钓看做是拷贝,钓都是一样的,但是等的过程不相同。

  • 张三:永远看着鱼漂,谁叫他都没有                                                ——阻塞式IO
  • 李四:一会看看鱼漂,一会看看书、刷书视频                                  ——非阻塞轮询式IO
  • 王五:铃铛绑在的鱼竿顶部(铃铛响了,就开始抬杆)                    ——信号驱动式IO
  • 赵六:100个鱼竿一起钓,哪个鱼漂动了就去哪里                            ——多路复用IO
  • 田七:发起了钓鱼,让助手小王去钓鱼,自己去干其他事情             ——异步IO

其中,阻塞、非阻塞、信号驱动、多路复用都是同步IO,他们都参与了IO的过程,要么等了、要么拷贝了、或者都做了。

而田七只是发起了钓鱼,然后就当甩手掌柜,交给小王去等去拷贝,自己并没有参与,他是异步IO。

在这个故事中,河流是操作系统,鱼是数据,鱼漂是数据就绪条件,鱼竿是文件描述符。

1.阻塞式IO

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

#include <iostream>
#include <unistd.h>
#include <fcntl.h>int main()
{while (true){char buff[1024];ssize_t s = read(0, buff, sizeof(buff - 1));if(s>0){buff[s] = '\0';std::cout<<"echo# "<<buff<<std::endl;}else if (s==0){std::cout<<"end stdin"<<std::endl;break;}else{//TODO}}
}

2.非阻塞式IO

阻塞IO:如果内核还未将数据准备好, 系统调用仍然会直接返回, 并且返回EWOULDBLOCK错误码。

非阻塞IO往往需要程序员循环的方式反复尝试读写文件描述符,这个过程称为轮询。这对CPU来说是较大的浪费, 一般只有特定场景下才使用。
 

#include <iostream>
#include <unistd.h>
#include <fcntl.h>
#include <cstdlib>//使用F_GETFL将当前的文件描述符的属性取出来(这是一个位图)。
//然后再使用F_SETFL将文件描述符设置回去, 设置回去的同时, 加上一个O_NONBLOCK参数
void SetNoBlock(int fd) 
{             // 获取fd文件描述符的状态标志int f1 = fcntl(fd, F_GETFL);if (f1 < 0){std::cerr << "fcntl error" << std::endl;exit(0);}// 设置fd文件描述符的状态标志   f1为老标志的内容,O_NONBLOCK为非阻塞fcntl(fd, F_SETFL, f1 | O_NONBLOCK);
}int main()
{SetNonBlock(0);while (true){char buff[1024];ssize_t s = read(0, buff, sizeof(buff) - 1);if (s > 0){buff[s] = '\0';std::cout << "echo# " << buff << std::endl;}else if (s == 0){std::cout << "end stdin" << std::endl;break;}else{// 非阻塞等待,数据没有准备好,返回值仍然是 -1  但不认为是出错// 因此我们需要查看错误码,看具体原因if (errno == EWOULDBLOCK || errno == EAGAIN){std::cout << "OS的底层数据还没有就绪,errno: " << errno << std::endl;}else if(errno == EINTR){std::cout << "IO 被信号中断,请再次尝试"<< std::endl;}else{//这里才是read出错break;}}sleep(1);}
}

3.信号驱动IO

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

4.多路复用IO

IO多路复用:虽然从流程图上看起来和阻塞IO类似。实际上最核心在于IO多路复用能够同时等待多个文件描述符的就绪状态

操作系统给我们提供了select系统调用,我们可以将很多文件描述符交给select管理。多个文件描述符就绪的概率是要比前面IO模式单个文件描述符就绪的概率高得多,当有文件描述符准备就绪,select不进行拷贝,而是通知应用程序,让应用程序去进行相应的IO处理,此时,是不会出现IO阻塞的情况,因为是收到的通知才进行的IO。大大提高了效率。

select的使用 

5.异步IO 

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

异步IO,只是发起的IO请求,由操作系统去完成IO等+拷贝的操作,最后吃现成的就行了。 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Volatility:分析MS10-061攻击
  • 【总结】逻辑运算在Z3中运用+CTF习题
  • C#实现数据采集系统-查询报文处理和响应报文分析处理
  • 【C++】C++类和对象详解(上)
  • Docker核心技术:容器技术要解决哪些问题
  • Python爬虫-淘宝搜索热词数据
  • 《0基础》学习Python——第二十二讲__网络爬虫/<5>爬取豆瓣电影封面图
  • uniapp封装请求拦截器,封装请求拦截和响应拦截的方法
  • c# 一个自定义日志类
  • 【JAVA 常用API】数据库字段存储JSON格式数据,JAVA中如何将List<Entity>或者对象实体转换为字符串
  • Linux shell编程学习笔记65: nice命令 显示和调整进程优先级
  • linux文本查看命令
  • 概率论原理精解【1】
  • 基于YOLO8的目标检测系统:开启智能视觉识别之旅
  • 【Linux】Linux的基本使用
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • “大数据应用场景”之隔壁老王(连载四)
  • 【剑指offer】让抽象问题具体化
  • AHK 中 = 和 == 等比较运算符的用法
  • angular学习第一篇-----环境搭建
  • canvas 绘制双线技巧
  • Facebook AccountKit 接入的坑点
  • Fundebug计费标准解释:事件数是如何定义的?
  • Git初体验
  • Java 实战开发之spring、logback配置及chrome开发神器(六)
  • Just for fun——迅速写完快速排序
  • Magento 1.x 中文订单打印乱码
  • React-Native - 收藏集 - 掘金
  • SOFAMosn配置模型
  • Swift 中的尾递归和蹦床
  • Vue组件定义
  • 创建一个Struts2项目maven 方式
  • 等保2.0 | 几维安全发布等保检测、等保加固专版 加速企业等保合规
  • 如何解决微信端直接跳WAP端
  • 思考 CSS 架构
  • 怎么将电脑中的声音录制成WAV格式
  • 找一份好的前端工作,起点很重要
  • ​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】
  • ​水经微图Web1.5.0版即将上线
  • #我与Java虚拟机的故事#连载09:面试大厂逃不过的JVM
  • (0)Nginx 功能特性
  • (2020)Java后端开发----(面试题和笔试题)
  • (html5)在移动端input输入搜索项后 输入法下面为什么不想百度那样出现前往? 而我的出现的是换行...
  • (pojstep1.1.2)2654(直叙式模拟)
  • (补充):java各种进制、原码、反码、补码和文本、图像、音频在计算机中的存储方式
  • (二)hibernate配置管理
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (四)鸿鹄云架构一服务注册中心
  • (原)记一次CentOS7 磁盘空间大小异常的解决过程
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • (转)【Hibernate总结系列】使用举例
  • (转)ORM
  • (转)Unity3DUnity3D在android下调试