【图解IO与Netty系列】IO的同步与异步、阻塞与非阻塞,Linux五种IO模型

IO的同步与异步、阻塞与非阻塞,Linux五种IO模型

  • IO的同步与异步,阻塞与非阻塞
    • 阻塞IO与非阻塞IO
    • 同步IO与异步IO
  • Linux五种IO模型
    • BIO
    • NIO
    • IO多路复用
    • 信号驱动IO
    • AIO

IO的同步与异步,阻塞与非阻塞

我们有时会看到类似于同步阻塞式IO、同步非阻塞式IO、异步IO等这些名词。

大多数时候,同步就是阻塞的,异步就是非阻塞的,比如我们并发编程里面加锁进行同步,那么获取不到锁的就要阻塞等待。但是在IO里面,同步异步与阻塞非阻塞不是同一概念。

这里面的同步、异步、阻塞、非阻塞是什么意思呢?

阻塞IO与非阻塞IO

在IO里面,当数据还没有就绪时,当前线程是否需要等待数据到达,可以分为阻塞IO与非阻塞IO。阻塞式IO是指当数据未就绪时,当前线程阻塞等待数据就绪;非阻塞式IO是指当数据未就绪时,当前线程不会阻塞等待数据就绪。

在这里插入图片描述

这里的数据就绪是指,数据已经加载到操作系统内核空间。比如网络IO,当数据到达网卡缓冲区,会通过DMA(Direct Memory Access——直接内存访问)设备把数据拷贝到内核空间,此时代表数据就绪,也就是等待应用程序拷贝到用户空间。

在这里插入图片描述

同步IO与异步IO

当数据已经达到了之后,就需要把内核空间的数据拷贝到用户空间,把内核空间的数据拷贝到用户空间是通过CPU进行拷贝。

在这里插入图片描述

是否需要当前线程主动去把内核空间中的数据搬运到用户空间,这又分为同步IO和异步IO。需要当前线程主动拷贝内核空间的数据到用户空间的叫同步读取,不需要当前线程主动拷贝内核空间的数据到用户空间的叫异步读取。

在这里插入图片描述

那么,根据同步与异步、阻塞与非阻塞,就组合出了四种类型的IO:

在这里插入图片描述

首先这里要知道,异步阻塞IO是不存在的,因此阻塞式IO在数据未就绪前是阻塞等待的,直到数据就绪之后当前线程才解阻塞,而数据都已经到达了,那直接拷贝到用户空间就可以了,这时候弄一个异步读取就没有必要了。

Linux五种IO模型

BIO

BIO是同步阻塞式IO。以网络IO为例,当客户端没有发送数据时,当前线程会阻塞等待数据,当客户端发送的数据被网卡接收并被DMA设备拷贝到内核空间之后,当前线程把内核空间中的数据拷贝到用户空间,然后当前线程才从数据拷贝中返回。

在这里插入图片描述

那么我们看到的现象就是,当服务端调用read()函数时,服务端当前线程阻塞等待客户端发送数据,当客户端发送的数据被服务端接收并拷贝到内核空间之后,服务端的当前线程需要把数据拷贝到用户空间,然后服务端当前线程才从read()函数返回。

在这里插入图片描述

NIO

NIO是同步非阻塞IO,当客户端没有发送数据时,服务端线程不会阻塞等待,而是马上返回,当前线程需要不断的检测数据是否已经到达并被拷贝到内核空间。如果数据还没有准备好,那么read函数调用会马上返回一个error,用户线程可以再次发起read函数调用继续检测;如果数据已经在内核空间了,那么当前线程调用read函数就会拷贝内核空间的数据到用户空间,这个拷贝的过程是同步读取,是当前线程主动拷贝的,因此在线程拷贝数据到用户空间的这段时间,程序是不会往下执行的。

在这里插入图片描述

NIO相比BIO的不同在于当数据还未就绪时,使用NIO是不会导致当前线程阻塞的,但是当数据就绪时,NIO与BIO一样是由当前线程拷贝到用户空间的,因此当要拷贝内核空间的数据到用户空间时,NIO与BIO是一样的会卡住直到数据拷贝完毕。

在这里插入图片描述

IO多路复用

在Linux操作系统上面,IO多路复用通过Linux提供的select、poll、epoll等API实现。使用IO多路复用是会使得当前线程阻塞的,但是IO多路复用与阻塞IO不同,阻塞IO是当前线程阻塞监听一个socket文件描述符,而IO多路复用则是阻塞监听多个socket文件描述符。

在这里插入图片描述

当有一个或多个文件描述符有数据就绪时,则该线程解阻塞,可以操作这些有数据就绪的socket文件描述符读取数据。

在这里插入图片描述

信号驱动IO

要理解信号驱动IO,首先要理解什么是信号驱动。信号驱动是一种软中断,是在软件层面模拟硬件中断实现的一种中断机制。

首先当前线程向操作系统注册一个信号处理函数,操作系统内核保持该信号处理函数。

在这里插入图片描述

当对应的事件发生时,操作系统向当前线程发送一个SIGIO信号。然后触发一个软中断,当前线程切换到内核态,执行之前注册的信号处理函数。执行完毕之后,再切换回用户态,当前线程从中断处开始往下执行。

在这里插入图片描述

可见这是一种异步操作,再对应的事件没有发生时,当前线程可以继续往下执行,不会阻塞,当对应的事件发生时,才转而执行预先注册的函数。

信号驱动IO也是一种同步非阻塞IO。当前线程通过sigaction函数注册一个SIGIO信号处理函数,然后回马上返回不会阻塞。如果客户端发送的数据已被拷贝到内核空间,操作系统会发送一个SIGIO信号给当前线程,当前线程转而执行之前注册的SIGIO信号处理函数,里面会调用redvfrom读取内核空间的数据到用户空间,此时是由当前线程主动拷贝数据,因此从内核空间拷贝数据到用户空间期间当前线程阻塞,因此还是同步IO。

在这里插入图片描述

AIO

AIO是异步IO,异步IO是全程无阻塞的IO操作,性能最高。应用程序不需要阻塞等待数据到达,当数据到达时操作系统自动把内核空间的数据拷贝到用户空间,再通知当前线程处理数据。

在这里插入图片描述

首先用户线程调用aio_read函数并传递用户空间缓存区、缓冲区大小等参数,然后马上返回,不会阻塞当前线程。当数据已在内核空间中就绪时,操作系统内核自动把数据拷贝到指定的用户空间缓冲区。当操作系统内核拷贝数据到用户空间完成后,再发送一个信号通知用户线程处理数据。

在这里插入图片描述

但可惜的是,Linux操作系统对AIO的支持不是很好,Linux的AIO是基于IO多路复用做的封装,性能并没有很大的提升,因此使用的更多的是IO多路复用。但是Windows操作系统则在真正意义上实现了AIO,因此在Windows操作系统环境下使用AIO的话,可以在性能上得到很大的提升。

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

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

相关文章

(避坑)SpringSecurity关于使用.antMatchers放行接口不生效问题

问题 在使用SpringSecurity的时候发现放行指定接口一直没有生效,使用"/**"就可以生效的问题 关于securityConfig的配置代码 Beanprotected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {http.csrf().disable() // 关闭csrf防护…

博客开始使用 Cache Master 缓存插件

明月在给大家推荐 Cache Master 插件的时候(可参考【推荐个比较纯正的缓存插件——Cache Master】一文),仅仅是在其他站点上试用了一下,今天明月正式在博客上用上了 Cache Master,没有想到对 Dragon 主题的支持竟然是出…

RUST 和 GO 如何管理它们的内存

100编程书屋_孔夫子旧书网 Go 中的内存管理 Go 中的内存不会在缓存键被驱逐时立即释放。 相反,垃圾收集器会经常运行以发现任何没有引用的内存并释放它。 换句话说,内存会一直挂起,直到垃圾收集器可以评估它是否真正不再使用,而…

rtsp协议分析

rtsp概述 rtsp (real-time stream protocol)实时流媒体控制协议。RFC2326:这是RTSP的初始定义版本v1.0,由哥伦比亚大学、网景和RealNetworks公司提交给互联网工程任务组(IETF)作为RFC标准。RFC7826:这是RTSP的后续更新…

Java进阶学习笔记14——模板方法设计模式

面试和看源码。 谈到设计模式: 1、解决了什么问题? 2、怎么写? 模板方法设计模式解决了什么问题? 解决方法中存在重复代码的问题。 写法: 1)定义一个抽象类: 2)在里面定义两个方…

C# 控制台应用模板可生成顶级语句

C# 控制台应用模板可生成顶级语句 项目2024/01/0810 个参与者 反馈 本文内容 使用新的程序样式隐式 using 指令全局 using 指令使用旧程序样式 从 .NET 6 开始,新 C# 控制台应用的项目模板在 Program.cs 文件中生成以下代码: C#复制 // See https…

C++ prime 第五版 第14章 重载运算与类型转换

一、基本概念 重载的运算符是具有特殊名字的函数:它们的名字由关键字operator和其后要定义的运算符号共同组成。和其他函数一样,重载的运算符也包含返回类型、参数列表以及函数体。 我们不能为内置类型的运算对象重定义运算符。对于一个运算符函数来说&…

某方protobuf闲谈

问题 当我们去看某方的时候,搜索了关键词svm,然后通过抓包查看,请求的Request Payload是一串看不懂的乱码,并且返回的数据也大部分是乱码 观察请求的Content-Type是application/grpc-web+proto,没错数据的传输是protobuf的形式了 protobuf的相关概念和原理,网上有很多教…

vulhub——Aria2、bash、catic

文章目录 一、Aria2 任意文件写入漏洞二、CVE-2014-6271(Bash Shell 漏洞)三、CVE-2022-46169(Cacti 前台命令注入漏洞) 一、Aria2 任意文件写入漏洞 Aria2是一个命令行下轻量级、多协议、多来源的下载工具(支持 HTTP…

docker-compose 搭建 单机版ELK

docker-compose 搭建 单机版ELK 前言 本次部署将使用ElasticSearch官方的镜像和Docker-Compose来创建单节点的ELK,用于学习ELK操作。在k8s集群内,如果每天的日志量超过20G以上,建议部署在k8s集群外部,以支持分布式集群的架构。在…

【WEB前端2024】开源智体世界:乔布斯3D纪念馆-第26节-内嵌blender展厅

【WEB前端2024】开源智体世界:乔布斯3D纪念馆-第26节-内嵌blender展厅 使用dtns.network德塔世界(开源的智体世界引擎),策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的智体世界…

网络编程的基础知识(适合新手)

网络编程 在Java中,网络编程是指使用Java语言进行网络通信的编程技术。这种技术使得位于不同地理位置的计算机能够通过网络进行通信,实现资源共享和信息传递。 一、定义 Java网络编程是Java语言在网络通信方面的应用,它利用Java提供的网络…

重开之数据结构(二刷)

引言: 由于前段时间学习效率不高,导致后面复习前面数据结构没有一个大纲,因此打算重新来学习以下数据结构,期望再次把数据结构学透,并有深刻的印象.并且记录每一次的学习记录 以便于后续复习 二分查找 需求:在有序数组arr内,查找target值 如果找到返回索引位置如果找不到返回…

c++(一)

c&#xff08;一&#xff09; C与C有什么区别命名空间使用 输入输出流引用指针和引用的区别定义拓展 函数重载例子测试函数重载原理 参数默认值什么是参数默认值注意 在c中如何引入c的库动态内存分配new、delete与malloc、free的区别&#xff1f; C与C有什么区别 <1>都是…

Introduction of Internet 计算机网络概述

计算机网络的概念 计算机网络的定义&#xff1a; 多台独立的计算机通过通信线路实现资源共享的计算机系统 计算机网络的组成 资源子网&#xff1a;提供共享的软件资源和硬件资源 通信子网&#xff1a;提供信息交换的网络结点和通信线路 计算机网络类型 按照拓扑排序 星型…

【STM32】计算定时器的溢出

TIM2、3、4、5、12、13、14在APB1上&#xff0c;最大计数频率84M。 TIM1、8、9、10、11在APB2上&#xff0c;最大计数频率168M。 time(arr1)/(prescale1)/Tclk 算出来的是秒 下图使用TIM14 84MHz 那么time33600*25000/8400000010S&#xff0c;10S进入一次中断 中断方式开…

基于STM32+NBIOT(BC26)设计的物联网观赏鱼缸

文章目录 一、前言1.1 项目介绍【1】开发背景【2】项目实现的功能【3】项目模块组成 1.2 设计思路 二、(硬件控制端)硬件选型2.1 STM32开发板2.2 PCB板2.3 USB下载线2.4 NBIOT模块2.5 杜邦线&#xff08;2排&#xff09;2.6 稳压模块2.7 电源插头2.8 水温检测传感器2.9 水质检测…

TiDB学习4:Placement Driver

目录 1. PD架构 2. 路由功能 2. TSO 2.1 TSO 概念 2.2 TSO分配过程 2.3 TSO时间窗口 3. 调度 3.1 信息收集 3.2 生成调度(operator) 3.3 执行调度 4. Label 与高可用 4.1 Label 的配置 5. 小结 1. PD架构 PD是整个TiDB的总控&#xff0c;相当于集群的大脑 PD集成了…

Android 版本与 API level 以及 NDK 版本对应

采用 Android studio 开发 Android app 的时候&#xff0c;需要选择支持的最低 API Level 和使用的 NDK 版本&#xff0c;对应开发 app 的最低 SDK 版本&#xff1a; 在 app 的 build.gradle 文件里&#xff0c;对应于代码如下&#xff1a; 目前各版本的占有率情况如下&#xf…

PaddleSeg训练推理及模型转换全流程

文章目录 1、数据准备1.1 数据标注1.2 数据导出1.3 标签较验1.4 数据集整理1.5 标签可视化 2、 模型训练3、模型验证4、模型推理5、模型导出6、导出文件的推理7、将模型转换成onnx8、使用onnx进行推理 本文记录一下使用paddleseg进行语议分割模型对人体进行分割的使用流程。事实…