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。大大提高了效率。

5.异步IO 

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

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

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

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

相关文章

【HarmonyOS】HarmonyOS NEXT学习日记:三、初识ArkUI

【HarmonyOS】HarmonyOS NEXT学习日记&#xff1a;三、初识ArkUI 忘掉HTML和CSS&#xff0c;ArkUI里构建页面的最小单位就是 “组件”&#xff0c;所以今天的目标就是认识一些常用的基础组件&#xff0c;以及他们的用法&#xff0c;对ArkUI形成一个基本认识。 基本组成 了解…

【前端】表单密码格式—校验。

如图&#xff1a;实现表单输入密码和确认密码的时候进行表单校验。 实现方式&#xff1a; 1.在代码的data里面定义&#xff0c;函数验证的方法。如图所示,代码如下 【代码】如下&#xff1a; const validatePassword (rule, value, callback) > {if (value ) {callback(n…

MongoDB自学笔记(三)

一、前文回顾 上一篇文章中我们学习了更新操作&#xff0c;以及讲解了部分的更新操作符&#xff0c;今天我们继续学习剩余的更新操作符。 二、更新操作符 1、$rename 语法&#xff1a;{ $rename: { < field1 >: < newName1 >, < field2 >: < newName2…

Java语言程序设计基础篇_编程练习题**14.29(游戏:豆机)

第十四章第二十九题 **14.29 (游戏&#xff1a;豆机) 请写一个程序&#xff0c;显示编程练习题 7.21 中介绍的豆机&#xff0c;如图 14-52c 所示 代码展示 package chapter_14;import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.layou…

【ffmpeg命令入门】重新编码媒体流、设置码率、设置帧速率

文章目录 前言ffmpeg的描述重新编码媒体流重新编码媒体流的命令ffmpeg支持的媒体流 设置视频码率视频码率是什么设置视频的码率 设置文件帧数率帧数率是什么ffmpeg设置帧数率 总结 前言 在数字媒体处理领域&#xff0c;ffmpeg是一款非常强大的工具&#xff0c;它可以用来进行媒…

Java | Leetcode Java题解之第242题有效的字母异位词

题目&#xff1a; 题解&#xff1a; class Solution {public boolean isAnagram(String s, String t) {if (s.length() ! t.length()) {return false;}int[] table new int[26];for (int i 0; i < s.length(); i) {table[s.charAt(i) - a];}for (int i 0; i < t.leng…

【面试题】Redo log和Undo log

Redo log 介绍Redo log之前我们需要了解一下&#xff0c;mysql数据操作的流程&#xff1a; 上述就是数据操作的流程图&#xff0c;可以发现sql语句并不是直接操作的磁盘而是通过操作内存&#xff0c;然后进行内存到磁盘的一个同步。这里我们必须要了解一些区域&#xff1a; 缓…

基于 asp.net家庭财务管理系统设计与实现

博主介绍&#xff1a;专注于Java .net php phython 小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设&#xff0c;从业十五余年开发设计教学工作 ☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不然下次找不到哟 我的博客空间发布了1000毕设题目 方便大家学习使用感兴趣的可以先…

抖音seo短视频账号矩阵系统源码-SaaS开源部署流程开发者技术分享

抖音seo账号矩阵系统&#xff0c;短视频矩阵系统源码&#xff0c; 短视频矩阵是一种常见的视频编码标准&#xff0c;通过多账号一键授权管理的方式&#xff0c;为运营人员打造功能强大及全面的“矩阵式“管理平台。使用矩阵系统也能保证账号的稳定性&#xff0c;降低账号的风险…

redis数据持久化之RDB大战AOF

华子目录 数据持久化RDB什么是RDB如何备份Fork持久化流程rdb持久化过程一、触发RDB持久化的方式二、RDB持久化的具体过程三、RDB持久化的优缺点 相关配置1.db文件名2.rdb文件和aof文件路径3.save示例 4.stop-writes-on-bgsave-errorstop-writes-on-bgsave-error 的配置选项和含…

Unity3d开发google chrome的dinosaur游戏

游戏效果 游戏中&#xff1a; 游戏中止&#xff1a; 一、制作参考 如何制作游戏&#xff1f;【15分钟】教会你制作Unity小恐龙游戏&#xff01;新手15分钟内马上学会&#xff01;_ unity教学 _ 制作游戏 _ 游戏开发_哔哩哔哩_bilibili 二、图片资源 https://download.csdn.…

ELK企业级日志分析

目 录 一、ELK简介 1.1 elasticsearch简介 1.2 logstash简介 1.3 kibana简介 1.4 ELK的好处 1.5 ELK的工作原理 二、部署ELK 2.1 部署elasticsearch(集群) 2.1.1 修改配置文件 2.1.2 修改系统参数 2.1.2.1 修改systemmd服务管理器 2.1.2.2 性能调优参数 2.1.2.3 …

电源模块企业该如何解决测试中的痛点问题?

根据研究发现&#xff0c;超过76%的企业在进行测试时会对产品质量、可靠性和测试速度这三项核心指标尤为重视。但是随着近几年的发展&#xff0c;目前的测试方法和措施对于这三项指标的测试远远无法达到企业的预期。被测产品的整体质量参差不齐、测试数据的可靠性以及测试的速度…

vue 如何做一个动态的 BreadCrumb 组件,el-breadcrumb ElementUI

vue 如何做一个动态的 BreadCrumb 组件 el-breadcrumb ElementUI 一、ElementUI 中的 BreadCrumb 定义 elementUI 中的 Breadcrumb 组件是这样定义的 <template><el-breadcrumb separator"/"><el-breadcrumb-item :to"{ path: / }">主…

yearrecord——一个类似痕迹墙的React数据展示组件

介绍一下自己做的一个类似于力扣个人主页提交记录和GitHub主页贡献记录的React组件。 下图分别是力扣个人主页提交记录和GitHub个人主页的贡献记录&#xff0c;像这样类似痕迹墙的形式可以比较直观且高效得展示一段时间内得数据记录。 然而要从0实现这个功能还是有一些麻烦得…

【数据结构】详解堆

一、堆的概念 堆(Heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵 完全二叉树的 数组对象。 堆是非线性数据结构&#xff0c;相当于一维数组&#xff0c;有两个直接后继。 如果有一个关键码的集合K { k₀&#xff0c;k₁&#xff0c;k₂ &#xff0…

PCB(印制电路板)制造涉及的常规设备

印制电路板&#xff08;PCB&#xff09;的制造涉及多种设备和工艺。从设计、制作原型到批量生产&#xff0c;每个阶段都需要不同的专业设备。以下是一些在PCB制造过程中常见的设备&#xff1a; 1. 计算机辅助设计&#xff08;CAD&#xff09;软件&#xff1a; - 用于设计PC…

3D问界—MAYA制作铁丝栅栏(透明贴图法)

当然&#xff0c;如果想通过建立模型法来实现铁丝栅栏的效果&#xff0c;也不是不行&#xff0c;可以找一下栅栏建模教程。本篇文章主要是记录一下如何使用透明贴图来实现创建铁丝栅栏&#xff0c;主要应用于场景建模&#xff0c;比如游戏场景、建筑场景等大环境&#xff0c;不…

问题清除指南|成功解决pipmatplotlib因为ConnectTimeoutError更新失败问题

前言&#xff1a;跑baseline需要升级matplotlib和pip&#xff0c;在此记录一个错误和一个「别致」的解决方案。 北京时间 14:00 左右&#xff0c;在终端环境中运行命令python -m pip install --upgrade pip&#xff0c;报错&#xff1a; 多次尝试&#xff0c;未果。 隔天上午 0…

Qt支持LG高级汽车内容平台

Qt Group与LG 电子&#xff08;简称LG&#xff09;正携手合作&#xff0c;将Qt软件框架嵌入其基于 webOS的ACPLG车载娱乐平台&#xff0c;用于应用程序开发。该合作旨在让原始设备制造商&#xff08;OEM&#xff09;的开发者和设计师能为汽车创建更具创新性的沉浸式汽车内容流媒…