详解Java中的五种IO模型

文章目录

  • 前言
    • 1、内核空间和用户空间
    • 2、用户态和内核态
    • 3、上下文切换
    • 4、虚拟内存
    • 5、DMA技术
    • 6、传统 IO 的执行流程
  • 一、阻塞IO模型
  • 二、非阻塞IO模型
  • 三、IO多路复用模型
    • 1、IO多路复用之select
    • 2、IO多路复用之epoll
    • 3、总结select、poll、epoll的区别
  • 四、IO模型之信号驱动模型
  • 五、IO 模型之异步IO(AIO)
  • 总结

前言

  • 在学习IO模型前,需要先了解些基础概念,才能理解IO的执行流程及阻塞的原因

1、内核空间和用户空间

  我们电脑上跑着的应用程序,其实是需要经过操作系统,才能做一些特殊操作,如磁盘文件读写、内存的读写等等。因为这些都是比较危险的操作,不可以由应用程序乱来,只能交给底层操作系统来。

  因此,操作系统为每个进程都分配了内存空间,一部分是用户空间,一部分是内核空间。内核空间是操作系统内核访问的区域,是受保护的内存空间,而用户空间是用户应用程序访问的内存区域。

  • 内核空间:主要提供进程调度、内存分配、连接硬件资源等功能
  • 用户空间:提供给各个程序进程的空间,它不具有访问内核空间资源的权限
    • 如果应用程序需要使用到内核空间的资源,则需要通过系统调用来完成
    • 进程从用户空间切换到内核空间,完成相关操作后,再从内核空间切换回用户空间

  我们应用程序是跑在用户空间的,它不存在实质的IO过程,真正的IO是在操作系统执行的。即应用程序的IO操作分为两种动作:IO调用和IO执行。IO调用是由进程(应用程序的运行态)发起,而IO执行是操作系统内核的工作。此时所说的IO是应用程序对操作系统IO功能的一次触发,即IO调用。

2、用户态和内核态

  • 如果进程运行于内核空间,被称为进程的内核态
  • 如果进程运行于用户空间,被称为进程的用户态

3、上下文切换

  CPU寄存器,是CPU内置的容量小、但速度极快的内存。而程序计数器,则是用来存储 CPU正在执行的指令位置、或者即将执行的下一条指令位置。它们都是CPU在运行任何任务前,必须的依赖环境,因此叫做CPU上下文。

  CPU上下文切换就是先把前一个任务的CPU上下文(也就是CPU寄存器和程序计数器)保存起来,然后加载新任务的上下文到这些寄存器和程序计数器,最后再跳转到程序计数器所指的新位置,运行新任务。

  一般我们说的上下文切换,就是指内核(操作系统的核心)在CPU上对进程或者线程进行切换。进程从用户态到内核态的转变,需要通过系统调用来完成。系统调用的过程,会发生CPU上下文的切换。

在这里插入图片描述

4、虚拟内存

  • 现代操作系统使用虚拟内存,即虚拟地址取代物理地址,使用虚拟内存可以有2个好处:
    • 虚拟内存空间可以远远大于物理内存空间
    • 多个虚拟内存可以指向同一个物理地址

  正是多个虚拟内存可以指向同一个物理地址,可以把内核空间和用户空间的虚拟地址映射到同一个物理地址,这样的话,就可以减少IO的数据拷贝次数啦。

在这里插入图片描述

5、DMA技术

  DMA,英文全称是Direct Memory Access,即直接内存访问。DMA本质上是一块主板上独立的芯片,允许外设设备和内存存储器之间直接进行IO数据传输,其过程不需要CPU的参与

在这里插入图片描述

  1. 用户应用进程调用read函数,向操作系统发起IO调用,进入阻塞状态,等待数据返回
  2. CPU收到指令后,对DMA控制器发起指令调度
  3. DMA收到IO请求后,将请求发送给磁盘
  4. 磁盘将数据放入磁盘控制缓冲区,并通知DMA
  5. DMA将数据从磁盘控制器缓冲区拷贝到内核缓冲区
  6. DMA向CPU发出数据读完的信号,把工作交换给CPU,由CPU负责将数据从内核缓冲区拷贝到用户缓冲区
  7. 用户应用进程由内核态切换回用户态,解除阻塞状态

  DMA的主要作用就是将数据从磁盘拷贝到内核缓冲区,这期间可以解放CUP去做其他事。

6、传统 IO 的执行流程

  • 传统的IO流程,包括read和write的过程
    • read:把数据从磁盘读取到内核缓冲区,再拷贝到用户缓冲区
    • write:先把数据写入到socket缓冲区,最后写入网卡设备

流程图如下:
在这里插入图片描述

读数据

  • 用户应用进程调用read函数,向操作系统发起IO调用,上下文从用户态转为內核态(切换1)
  • DMA控制器把数据从磁盘中,读取到内核缓冲区
  • CPU把内核缓冲区数据,拷贝到用户应用缓冲区,上下文从内核态转为用户态(切换2),read函数返回

写数据

  • 用户应用进程通过write函数,发起IO调用,上下文从用户态转为内校态(切换3)
  • CPU将应用缓冲区中的数据,拷贝到socket缓冲区
  • DMA控制器把数据从socket缓冲区,拷贝到网卡设备,上下文从内校态切换回用户态(切换4),write函数返回

  从流程图可以看出,传统IO的读写流程,包括了4次上下文切换(4次用户态和内核态的切换),4次数据拷贝(两次CPU拷贝以及两次的DMA拷贝)。

一、阻塞IO模型

  应用程序的进程发起IO调用,但是如果内核的数据还没准备好的话,那应用程序进程就一直在阻塞等待,一直等到内核数据准备好了,从内核拷贝到用户空间,才返回成功提示,此次IO操作,称之为阻塞IO

在这里插入图片描述

  • 阻塞IO比较经典的应用就是阻塞socketJava BIO
  • 阻塞IO的缺点就是:如果内核数据一直没准备好,那用户进程将一直阻塞,浪费性能,可以使用非阻塞IO优化

二、非阻塞IO模型

  如果内核数据还没准备好,系统调用会立即返回一个调用失败的信息,让它不需要等待,而是通过轮询的方式再来请求。如果内核数据准备好,在数据从内核拷贝到用户空间期间是阻塞的(因为现在是CUP在操作,之前准备数据是DMA)。

在这里插入图片描述

  • 同步非阻塞 IO 的优点是每次发起的IO系统调用在内核等待数据过程中可以立即返回,用户线程不会阻塞,实时性较好
  • 同步非阻塞IO的缺点是不断地轮询内核,这将占用大量的CPU时间,效率低下

三、IO多路复用模型

  在这之前,我们先来复习下,什么是文件描述符fd(File Descriptor),它是计算机科学中的一个术语,形式上是一个非负整数。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。

  IO复用模型核心思路:系统给我们提供一类函数(如我们耳濡目染的selectpollepoll函数),它们可以同时监控多个fd的操作,任何一个返回内核数据就绪,应用进程再发起recvfrom系统调用。

1、IO多路复用之select

  应用进程通过调用select函数,可以同时监控多个fd,在select函数监控的fd中,只要有任何一个数据状态准备就绪了,select函数就会返回可读状态,这时应用进程再发起recvfrom请求去读取数据。

  非阻塞IO模型(NIO)中,需要N(N>=1)次轮询系统调用,然而借助select的IO多路复用模型,只需要发起一次询问就够了,大大优化了性能。

在这里插入图片描述

select缺点

  • 监听的IO最大连接数有限,在Linux系统上一般为1024
  • select函数返回后,是通过遍历fdset,找到就绪的描述符fd。(仅知道有I/O事件发生,却不知是哪几个流,所以遍历所有流)

  因为存在连接数限制,所以后来又提出了poll。与select相比,poll解决了连接数限制问题。但是呢,select和poll一样,还是需要通过遍历文件描述符来获取已经就绪的socket。如果同时连接的大量客户端,在一时刻可能只有极少处于就绪状态,伴随着监视的描述符数量的增长,效率也会线性下降。因此经典的多路复用模型epoll诞生。

2、IO多路复用之epoll

  为了解决select/poll存在的问题,多路复用模型epoll诞生,它采用事件驱动来实现。

在这里插入图片描述

  epoll先通过epoll_ctl()来注册一个fd(文件描述符),一旦基于某个fd就绪时,内核会采用回调机制,迅速激活这个fd,当进程调用epoll_wait()时便得到通知。这里去掉遍历文件描述符的操作,而是采用监听事件回调的机制。这就是epoll的亮点。

3、总结select、poll、epoll的区别

selectpollepoll
底层数据结构数组链表红黑树和双链表
获取就绪的fd遍历遍历事件回调
事件复杂度O(n)O(n)O(1)
最大连接数1024无限制无限制
fd数据拷贝每次调用select,需要将fd数据从用户空间拷贝到内核空间每次调用poll,需要将fd数据从用户空间拷贝到内核空间使用内存映射(mmap),不需要从用户空间频繁拷贝fd数据到内核空间

  epoll明显优化了IO的执行效率,但在进程调用epoll_wait()时,仍然可能被阻塞。能不能酱紫:不用我老是去问你数据是否准备就绪,等我发出请求后,你数据准备好了通知我就行了,这就诞生了信号驱动IO模型。

四、IO模型之信号驱动模型

  信号驱动IO不再用主动询问的方式去确认数据是否就绪,而是向内核发送一个信号(调用sigaction的时候建立一个SIGIO的信号),然后应用用户进程可以去做别的事,不用阻塞。当内核数据准备好后,再通过SIGIO信号通知应用进程,数据准备好后的可读状态。应用用户进程收到信号之后,立即调用recvfrom,去读取数据。

在这里插入图片描述

  信号驱动IO模型,在应用进程发出信号后,是立即返回的,不会阻塞进程。它已经有异步操作的感觉了。但是你细看上面的流程图,发现数据复制到应用缓冲的时候,应用进程还是阻塞的。回过头来看下,不管是BIO,还是NIO,还是信号驱动,在数据从内核复制到应用缓冲的时候,都是阻塞的。还有没有优化方案呢?AIO(真正的异步IO)

五、IO 模型之异步IO(AIO)

  AIO也就是NIO2。Java7中引入了NIO的改进版NIO2,它是异步IO模型

在这里插入图片描述

AIO 用来解决数据复制阶段的阻塞问题

  • 同步意味着,在进行读写操作时,线程需要等待结果,还是相当于闲置
  • 异步意味着,在进行读写操作时,线程不必等待结果,而是将来由操作系统来通过回调方式由另外的线程来获得结果

总结

阻塞、非阻塞、同步、异步IO划分

在这里插入图片描述

BIO、NIO、AIO

  • 同步阻塞(blocking-IO)简称BIO
  • 同步非阻塞(non-blocking-IO)简称NIO
  • 异步非阻塞(asynchronous-non-blocking-IO)简称AIO

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

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

相关文章

网络安全产品---态势感知EDR

态势感知 what SA,Situational Awareness 是对一定时间和空间内的环境元素进行感知,并对这些元素的含义进行理解,最终预测这些元素在未来的发展状态。 why 安全防护思想已经从过去的被动防御向主动防护和智能防护转变。如果不做到主动防御…

Hadoop1X,Hadoop2X和hadoop3X有很大的区别么?

Hadoop的演进从Hadoop 1到Hadoop 3主要是为了提供更高的效率、更好的资源管理、更高的可靠性以及对更多数据处理方式的支持。下面是Hadoop 1, Hadoop 2, 和 Hadoop 3之间的主要区别和演进的原因: Hadoop 1 特点: 主要包括两大核心组件:HDFS&a…

跨平台SIP 客户端-linphone下载、使用、开启视频H264

linphone 介绍 Linphone 是一种开源的语音和视频通信应用程序,它提供了基于互联网协议(IP)的实时通信功能。用于语音/视频通话、即时消息和电话会议的开源 SIP 电话。它适用于移动和桌面环境(iOS、Android、GNU/Linux、macOS、Win…

【Linux】在centos快速搭建K8S1.18集群

使用 kubeadm 创建集群帮助文档 如果您需要以下几点,该工具是很好的选择:kubeadm 一种简单的方法,让你尝试 Kubernetes,可能是第一次。现有用户自动设置群集并测试其应用程序的一种方式。其他生态系统和/或安装程序工具中的构建…

SpringBoot集成Sleuth

引入Maven依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-sleuth</artifactId></dependency> 配置yml文件 bootstrap.yml文件增加如下配置 注&#xff1a;这个配置不是必须要&#…

经典机器学习算法——决策树

优质博文&#xff1a;IT-BLOG-CN 树模型是机器学习中最常用的一类模型&#xff0c;包括随机森林、AdaBoost、GBDT&#xff08;XGBoost和Lightgbm&#xff09;等&#xff0c;基本原理都是通过集成弱学习器的即式来进一步提升准确度。这里的弱学习器包括线性模型和决策树模型&…

大sql mysql执行

先把sql 拆分 太大的执行失败 使用 SQLDumpSplitter3 拆分sql 执行拆分的sql 拆分的sql 打开发现很多 ; 开头的空行 替换掉 正则 ^; 修改数据库 my.cnf my,ini 执行可能会提示 [ERR] 2006 - Server has gone away 错误 在 [mysqld] 添加以下几行 wait_timeout2880000 inter…

上位机工作感想-从C#到Qt的转变-1

0.前言 接触Qt开发也有一年多的时间了&#xff0c;还记得去年初从杭州回合肥时&#xff0c;刚来公司面临的几个问题&#xff1a; 1.C#转上位机的迷茫2.新公司管理模式的差异3.试用期的各种紧急任务。 当时也是加班加点学习C和Qt的基础知识&#xff0c;做了两个考核项目后&am…

解决Mac使用Vscode无法调用外部终端

前言 今天遇到一个很奇怪的问题&#xff0c;之前好好的用Vscode还能调用外部终端&#xff0c;怎么今天不行了&#xff1f;问题出在哪里呢&#xff1f;请听我娓娓道来。 检查配置文件 我查看了一下配置文件&#xff0c;发现配置文件都是调用外部控制台&#xff0c;没毛病啊。 …

【AI开发:音频】二、GPT-SoVITS使用方法和过程中出现的问题(GPU版)

1.FileNotFoundError: [Errno 2] No such file or directory: logs/guanshenxxx/2-name2text-0.txt 这个问题中包含了两个&#xff1a; 第一个&#xff1a;No module named pyopenjtalk 我的电脑出现的就是这个 解决&#xff1a;pip install pyopenjtalk 第二个&#xff1a…

快速排序题目SelectK问题(力扣75.颜色分类、力扣215.数组中的第K个最大元素、面试题17.14最小K个数)

力扣75.颜色分类 给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums &#xff0c;原地对它们进行排序&#xff0c;使得相同颜色的元素相邻&#xff0c;并按照红色、白色、蓝色顺序排列。 我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。 必须在不使用库内置的 sor…

从零开始的vscode配置及安装rust教程

配置vscode的rust环境 下载安装vscodemac 环境1. 下载安装rust2. 配置 mac vscode环境3. 创建一个测试项目 windows 环境1. 安装c运行环境2. 安装配置rustup3. 配置windows vscode环境4. 创建一个测试项目 下载安装vscode 1.官网应用程序下载 vscode&#xff1a;https://code.v…

注意力机制中多层的作用

1.多层的作用 在注意力机制中&#xff0c;多层的作用通常指的是将注意力机制堆叠在多个层上&#xff0c;这在深度学习模型中被称为“深度”或“多层”注意力网络。这种多层结构的作用和实现过程如下&#xff1a; 1. **逐层抽象**&#xff1a;每一层都可以捕捉到输入数据的不同…

在ubuntu20.04下迁移anaconda的目录,试验不行后,换成软连接

一、原因 随着不断的搭建不同的算法环境&#xff0c;原本在固态硬盘上安装的anaconda上占用空间越来越多。导致可用的固态硬盘空间越来越少&#xff0c;又因安装的环境太多&#xff0c;重新搭建比较费时费力。有没有直接将当前已经搭建好环境的anaconda 迁移到另外的目录呢&…

SAP 销售业务中免费货物的会计核算

此博文主要介绍SAP销售业务中免费货物解决方案中&#xff0c;免费货物的会计核算。如果需要进一步了解SAP SD 销售与分销业务中&#xff0c;免费货物的标准解决方案概览&#xff0c;可先了解本博客博文&#xff1a;SAP销售与分销中的免费货物解决方案相关文章&#xff1a; htt…

Python 全栈安全(一)

原文&#xff1a;annas-archive.org/md5/712ab41a4ed6036d0e8214d788514d6b 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 前言 序言 多年前&#xff0c;我在亚马逊搜索了一本基于 Python 的应用程序安全书。我以为会有多本书可供选择。已经有了很多其他主题的 Pyt…

【设计模式】单例模式|最常用的设计模式

写在前面 单例模式是最常用的设计模式之一&#xff0c;虽然简单&#xff0c;但是还是有一些小坑点需要注意。本文介绍单例模式并使用go语言实现一遍单例模式。 单例模式介绍 简介 单例模式保证一个类仅有一个实例&#xff0c;并提供一个访问它的全局访问点。 使用场景&#…

DC学习笔记

视频 数字逻辑综合工具实践 DC 01_哔哩哔哩_bilibili 一、DC工作模式&#xff08;此小节为搬运内容&#xff09; 原链接&#xff1a;Design_Compiler User Guide 随手笔记&#xff08;9&#xff09;Using Floorplan Information - 知乎 DC拥有四种工作模式&#xff1a; 工…

项目7-音乐播放器6+评论区

1.准备前端界面 前端小白&#xff1a;怎么为你的网页增加评论功能&#xff1f;&#xff08;一&#xff09;_为网页添加评论区怎么弄-CSDN博客 参考的上述文章的前端代码 我们从上述前端图片知道&#xff0c;我们数据库需要准备的字段&#xff1a; id,commentuserName,coomen…

字节FE:JavaScript学习路线图

JavaScript简介 JavaScript是一种高级的、解释执行的编程语言。它是互联网的三大核心技术之一&#xff0c;与HTML和CSS一同工作&#xff0c;用于创建交互式的网页。JavaScript被所有现代网页浏览器支持而不需要任何插件。它可以增强用户界面和网页的交互性&#xff0c;可以进行…