同步IO, 异步IO的理解

什么是IO?

在计算机中无时无刻不存在着对数据的访问和读取(数据都存储在物理的媒介上,例如寄存器,高速缓存,内存,磁盘,网卡等等),这些操作被称为IO。

阻塞IO

  • 当用户线程发起IO请求后,会进行系统调用(system call)来让内核(Kernel)进行IO操作
  • 此时用户线程阻塞,等待内核将数据准备好
  • 内核将数据准备好后会将数据从内核空间拷贝到用户空间,并返回给用户线程结束阻塞。

非阻塞IO

  • 由用户线程发起IO请求, 进行系统调用来让内核进行IO操作
  • 此时如果内核没有准备好数据则会直接返回error,并不会阻塞用户线程,用户线程可以重复的发起IO请求
  • 当用户线程发起请求并且内核已经将数据准备好后,会将数据从内核空间拷贝到用户空间(这个过程是需要阻塞用户线程的),返回给用户

多路复用IO

  • 用户线程调用select后进行系统调用(内核会监视所有select负责的socket),此时用户线程被阻塞
  • 当内核将数据准备好后就会返回,并通知用户线程进行读取操作,此时内核将数据拷贝到用户空间并返回

异步IO

  • 用户线程进行aio_read,进行系统调用切换到内核
  • 内核立即返回,并不会阻塞用户线程
  • 内核准备好数据后会将数据从内核空间拷贝到用户空间并通知用户线程操作已完成

阻塞IO与非阻塞IO?

阻塞IO:用户线程发起IO操作,紧接着由内核线程来执行IO操作,在阻塞IO中内核线程并不会立即返回而是等待数据拷贝到内存空间时才返回,在此期间用户线程处于阻塞状态。

非阻塞IO: 与阻塞IO不同,内核线程在执行IO操作后会立即返回,若结果为error则用户线程可以重新发起请求而不会被阻塞,一旦内核将数据准备好了且用户线程发起了IO请求那么将数据拷贝到用户空间。

我们看上面的图可以知道IO操作大致分为两个部分:

  • 用户线程发起IO请求时,内核未准备好数据
  • 用户线程发起IO请求时,内核以准备好数据 通过对比两个图中流程我们可以发现,(2)这个流程在阻塞IO与非阻塞IO流程是相同的区别在于(1)这个步骤。因此阻塞IO与非阻塞IO的区别在于内核线程在执行IO操作时是否立即返回结果,若立即返 回则为非阻塞IO,反之则为阻塞IO。

同步与异步IO?

  • 异步IO: 用户线程发起IO操作后,可以立即去做其他事情,另一方面,对于内核线程当它收到异步读取之后会立即返回,不会对用户线程造成阻塞。当内核将数据准备好之后会将数据从内核空间拷贝到用户空间,内核会发送 给用户一个信号通知用户IO操作已完成。

  • 同步IO: 同步IO的关键在于在真正读取数据(也就是上面提到的(2)这个步骤)的时候用户线程是否被阻塞。非阻塞IO虽然在用户发起请求时会立即返回,但是当内核准备好数据之后,任然需要用户线程发起请求才会将数据 从内核空间拷贝到用户空间,因此非阻塞IO属于同步IO。

异步IO与非阻塞IO的区别?

异步IO与非阻塞IO的区别在于,当用户线程发起一次IO操作不需要再次去确认内核是否准备好数据。异步IO中内核准备好数据后会将数据从内核空间自动拷贝到用户空间。

最后统一的总结一下:

用户进程发起请求从内核中获取数据那么这时候有两种情况:

  • 操作系统还没有准备后数据,那么这时候怎么办,有两种方法:

a. 让用于进程等着(这种情况就是阻塞)

b. 如果没有数据就返回一个ERROR,不需要用户进程干等(这种情况就是非阻塞)

  • 过了一会儿操作系统准备好数据了,这时候又有两种方法:

a. 啥也不管,等着用户进程再次来请求才把数据给它(这种情况就是同步)

b. 负责到底,数据准备好,直接给到用户进程,并且还发出一个信号,告诉用户进程数据已经准备好(这种情况就是异步)

因此,我们可以发现:不管是阻塞IO,还是非阻塞IO都是同步IO。

Original: https://www.cnblogs.com/liwangcai/p/11823025.html
Author: 神奇海螺。
Title: 同步IO, 异步IO的理解

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/574176/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Spring事件监听机制源码解析

    Spring事件监听器使用 1.Spring事件监听体系包括三个组件:事件、事件监听器,事件广播器。 事件:定义事件类型和事件源,需要继承ApplicationEvent。 pac…

    Java 2023年6月13日
    064
  • 并发编程的基础知识篇

    计算机与进程和线程之间的关系 1.计算机中有一个重要的指标就是CPU,而CPU中又有一个重要的指标就和核心数。 2.每当我们开启一个软件的时候,如QQ,微信(运行中的程序,被称为进…

    Java 2023年6月15日
    080
  • 每日一考-9.15

    wait和sleep的区别 简说:wait释放🔒,sleep不释放🔒 例子:买票过程中,当程序进行上锁后 sleep控制下的线程,买票是一一完成,当程序休眠后,sleep不会释放🔒…

    Java 2023年6月16日
    058
  • java中的set接口(Hashset,LinkedHashset,TreeSet)

    Hashset介绍 HashSet实际上是HashMap,底层都一样(数组+链表+红黑树) 不能有重复的元素,记住深入理解,可以添加不同的对象的,在前面的随笔中讲过了,只能有一个n…

    Java 2023年6月6日
    076
  • 进程 线程 协程

    黑书 计算机操作系统中说了很多。 首先,在一个cpu的情况下,进程是一个程序运行时的总和,一个时刻肯定只有一个进程在执行,只是cpu会使用进程调度算法来回切换进程而已,就绪,运行,…

    Java 2023年5月30日
    065
  • tengine、nginx配置正向代理,其他内网机器通过代理访问外网,支持https

    cd /usr/local/src wget https://tengine.taobao.org/download/tengine-2.3.3.tar.gz tar zxvf t…

    Java 2023年5月30日
    046
  • Oracle表主键作为外键都用在哪些表查询

    Oracle外键关联查询 Oracle中,如果设置了外键,删除数据时,必须将外键关联一并删除,但是如果对项目不是很熟悉时,我们无法判断到底都在哪些表中有外键关联,以下提供了一个查询…

    Java 2023年6月13日
    056
  • http服务端架构演进

    摘要 在 详解http报文相关文章中我们介绍了http协议是如何工作的,那么构建一个真实的网…

    Java 2023年6月8日
    082
  • Mac常用shell命令

    几个常用命令 命令名称:pwd英文:print work directory描述:查看当前工作目录的完整路径 英文全称: list描述:列出目录下的内容清单常用参数:-l:列出文件…

    Java 2023年6月13日
    076
  • Spring Boot 使用 Log4j2

    Java 中比较常用的日志工具类,有 Log4j、SLF4j、Commons-logging(简称jcl)、Logback、Log4j2(Log4j 升级版)、Jdk Loggin…

    Java 2023年5月30日
    071
  • idea如何在创建类的同时加入作者的名字和时间等

    1、打开idea,左上角file-settings 2、在setting窗口找到editor目录下的”file and code template” 3、在…

    Java 2023年6月7日
    086
  • SpringBoot整合SpringSecurityOauth2实现鉴权-动态权限

    写在前面 思考:为什么需要鉴权呢? 系统开发好上线后,API接口会暴露在互联网上会存在一定的安全风险,例如:爬虫、恶意访问等。因此,我们需要对非开放API接口进行用户鉴权,鉴权通过…

    Java 2023年6月16日
    090
  • ArrayList源码

    ArrayList源码 目录 一、ArrayList 1.1 包含的属性 1.2 源码分析 1.2.1 add源码分析 1.2.2 grow源码 一、ArrayList Array…

    Java 2023年6月5日
    068
  • Recyclerview、ViewPager 多重嵌套,滑动处理

    在项目中出现多重嵌套情况时,会出现无法滑动的场景,比如经常碰到的场景 ViewPager -> Fragment -> RecyclerView -> Recyc…

    Java 2023年6月7日
    0129
  • javaweb学生管理系统 第一次总结

    JavaWeb 学生管理系统 第一次总结 ; 具备的知识 java se 高级数据库jsselvetEl表达式jsp 项目 目录结构 [外链图片转存失败(img-dfQq8aOt-…

    Java 2023年6月8日
    083
  • Mybatis-Plus使用@TableField实现自动填充日期

    一、前言 我们在日常开发中经常使用ORM框架,比如Mybatis、tk.Mybatis、Mybatis-Plus。不过最广泛的还是Mybatis-Plus,我们的一些表,都会有创建…

    Java 2023年6月15日
    073
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球