一个IO操作涉及两个系统对象:

  • 调用这个IO的用户Process/Thread
  • 系统内核 - System Kernel

一个具体的Read操作包括两个阶段:

  • 内核等待数据准备就绪:Waiting for the data to be ready
  • 从内核向用户进程/线程拷贝数据:Copying the data from the Kernel to the Process/Thread

只有在同步的情况下才会有“阻塞”和“非阻塞”之说,异步情况,必须是非阻塞的!

“同步 - 异步”指访问数据的一种协作方式,同步需要主动读写数据,在读写数据的过程中还是会阻塞;异步只需要I/O操作完成的通知,并不主动读写数据,由内核完成数据的读写。“阻塞 - 非阻塞”指进程/线程要访问的数据是否就绪,进程/线程是否需要等待。同步和异步着重点在于多个任务的执行过程中,一个任务的执行是否会导致整个流程的暂时等待,阻塞和非阻塞着重点在于发出一个请求操作时,如果进行操作的条件不满足是否会返会一个标志信息告知条件不满足。

同步/异步仅关注消息通知的方式,并不关心消息如何处理,消息处理过程中应用程序(线程)的状态用阻塞/非阻塞来描述,是函数/方法的实现方式。

参考:socket阻塞与非阻塞、同步与异步概念详解 - 1socket阻塞与非阻塞、同步与异步概念详解 - 2

同步 vs 异步

消息的通知机制,针对Client端(和Server端的交互),进程/线程触发IO操作后:

  • 同步:进程/线程等待IO操作完成(阻塞)或轮询查看IO操作是否完成(非阻塞);
  • 异步:直接返回,进程/线程做自己的事情,IO操作交给内核处理、完成后内核通知进程/线程;

其中,异步中处理的执行部通过三种途径返回结果给调用者:

  • 状态:需要调用者定时检查,效率低;
  • 通知:效率高;
  • 回调函数:类似通知;

同步 Synchronous

A Synchronous-I/O operation causes the requesting process to be blocked until that I/O operation completes.

 串行,无条件等待,具体见下前4种I/O。

异步 Asynchronous

An Asynchronous-I/O operation does not cause the requesting process to be blocked.

 并发,无需等待、无需轮询,具体见下异步I/O。

阻塞 vs 非阻塞

应用程序在等待消息时的状态,针对Server端,Server端是否阻塞与Client端无关,至于Client端在等待的前提下啥也不做还是边做其他事边等待,由Client端自己决定。关于阻塞/非阻塞,在网络编程中通常应用在是不是需要等待数据就绪。

阻塞 Blocking

 挂起等待,具体见下阻塞I/O。

非阻塞 Non-Blocking

 轮询检查等待,具体见下非阻塞I/O。

参考:怎样理解阻塞非阻塞与同步异步的区别? - 知乎

I/O模型

阻塞I/O(Blocking I/O)

进程阻塞等待,进程挂起睡眠直到数据拷贝完成。

简单易实现,不适于同时处理大量套接字、扩展性差。改进:

  • 多进程/线程;
  • 线程池或连接池;

非阻塞I/O(Non-Blocking I/O)

进程非阻塞等待,数据准备阶段进程不睡眠而是轮询等待(导致CPU占用率高)、数据拷贝阶段进程阻塞。

便于处理多套接字的通信,但实现复杂、需仔细检查返回代码并对收到的错误信息进行处理。

I/O多路复用(I/O Multiplexing) Reactor模式

对一个IO端口,两次调用、两次返回。

数据准备阶段进程阻塞等待于select()/epoll()、数据拷贝阶段进程阻塞,其中select()可以同时阻塞多个I/O端口的操作,直到某个端口有数据可读/写时,才真正调用I/O操作函数。 实现同时对多个IO端口进行监听,适于处理大量套接字的连接。

I/O多路复用经典模式(2种):

  • 基于同步I/O的Reactor
  • 基于异步I/O的Proactor

参考:Reactor和Proactor

信号驱动I/O(Signal Driven I/O)

两次调用,两次返回。

数据准备阶段进程继续执行、数据拷贝阶段进程阻塞。 需要建立信号处理程序。

异步I/O(Asynchronous I/O) Proactor模式

 无阻塞,无需等待、无需轮询、无需多线程。

异步过程调用,调用者不能立刻得到结果,实际处理这个调用的部件在完成处理后,通过状态、通知或回调来通知调用者。异步需操作系统的底层支持。

:信号驱动模型由内核通知用户可以开始一个IO操作(数据在内核缓冲区中),异步IO由内核通知IO操作已经完成(数据已在用户空间中)。

比较

同步IO - 异步IO:数据访问时的消息通知机制,数据访问/拷贝时(第二阶段)进程是否等待,主动等待还是被动通知等待消息的触发! 同步IO和异步IO的关键区别反映在数据拷贝阶段是由用户线程完成还是内核完成。

阻塞IO - 非阻塞IO:等待数据就绪时(第一阶段)应用程序的调用是否立即返回!

推荐书籍:

  • Richard Stevens -《UNIX网络编程 - 卷1》:第六章

参考:

谈I/O模型的更多相关文章

  1. 老李谈JVM内存模型

    老李谈JVM内存模型   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:908821478,咨 ...

  2. 【Linux】浅谈I/O模型

    关于I/O模型的引出 我们都知道,为了OS的安全性等的考虑,进程是无法直接操作I/O设备的,其必须通过系统调用请求内核来协助完成I/O动作,而内核会为每个I/O设备维护一个buffer. 如下图所示: ...

  3. 浅谈Java内存模型

    Java内存模型虽说是一个老生常谈的问题 ,也是大厂面试中绕不过的,甚至初级面试也会问到.但是真正要理解起来,还是相当困难,主要这个东西看不见,摸不着.网上已经有大量的博客,但是人家的终究是人家的,自 ...

  4. 浅谈CSS盒子模型

    [摘要]盒子模型是CSS中的一个重要概念,虽然CSS中没有盒子这个单独的属性对象,但它却是CSS中无处不在的一个重要组成部分.掌握盒子模型的原理和使用方法可以极大地丰富HTML元素的表现效果,同时对于 ...

  5. 浅谈css盒模型

    在我们网页上的每一个元素,一个按钮,一段文本,一张图片等等,浏览器都将它们当做一个“盒子”看待,并把这样的盒子称为盒模型(box model).使用Chrome的右键>审查元素对某个网页上的元素 ...

  6. 浅谈隐语义模型和非负矩阵分解NMF

    本文从基础介绍隐语义模型和NMF. 隐语义模型 ”隐语义模型“常常在推荐系统和文本分类中遇到,最初来源于IR领域的LSA(Latent Semantic Analysis),举两个case加快理解. ...

  7. Java NIO1:浅谈I/O模型

    一.什么是同步?什么是异步? 同步和异步的概念出来已经很久了,网上有关同步和异步的说法也有很多.以下是我个人的理解: 同步就是:如果有多个任务或者事件要发生,这些任务或者事件必须逐个地进行,一个事件或 ...

  8. [JS学习笔记]浅谈Javascript事件模型

    DOM0级事件模型 element.on[type] = function(){} 兼容性:全部支持   lay1 lay2 lay3 e.target:直接触发事件的元素[IE8及以下不支持tage ...

  9. 浅谈I/O模型

    在学习线程,NIO等知识时都需要知道一些基础知识. 一.什么是同步或异步 同步:个人通俗理解多个人排队打饭一个窗口,只有前面一个人打完了,后面的人才能打.如果前面人因为什么原因一直站在那里不走,后面的 ...

随机推荐

  1. ENode框架使用场景简述

    ENode是一个.NET平台下,纯C#开发的,基于DDD,CQRS,ES,EDA,In-Memory架构风格的,可以帮助开发者开发高并发.高吞吐.可伸缩.可扩展的应用程序. 开源项目地址:https: ...

  2. Backbone源码分析(一)

    距离上一篇博客有一段时间了,期间各种琐事萦绕.最主要的一件是,当我差不多将整个dojo核心源码看完,惊讶的发现dojo1.*的设计以是老态龙钟之象,而我沉溺在dojo中太久,已经不知道前端世界变成了什 ...

  3. 《Entity Framework 6 Recipes》中文翻译系列 (27) ------ 第五章 加载实体和导航属性之关联实体过滤、排序、执行聚合操作

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-9  关联实体过滤和排序 问题 你有一实体的实例,你想加载应用了过滤和排序的相关 ...

  4. HTML5 音频播放器-Javascript代码(短小精悍)

    直接上干货咯! //HTML5 音频播放器 lzpong 2015/01/19 var wavPlayer = function () { if(window.parent.wavPlayer) re ...

  5. ios crash的原因与抓取crash日志的方法

    首先我们经常会闪退的异常有哪些呢?crash的产生来源于两种问题:违反iOS策略被干掉,以及自身的代码bug. 1.IOS策略 1.1 低内存闪退 前面提到大多数crash日志都包含着执行线程的栈调用 ...

  6. Java 的设计模式之一装饰者模式

    刚开始接触装饰者的设计模式,感觉挺难理解的,不够后来花了一个晚上的时间,终于有头绪了 装饰者设计模式:如果想对已经存在的对象进行装饰,那么就定义一个类,在类中对已经有的对象进行功能的增强或添加另外的行 ...

  7. junit测试,使用classpath和file 加载文件的区别

    用junit测试发现一个问题,怎么加载配置文件?一直都出现这样的错误 ERROR: org.springframework.test.context.TestContextManager - Caug ...

  8. oracle数据库表的导入导出cmd命令大全

    在实际的项目开发中经常会遇到导入导出oracle数据库中的表,以下是常用的一些cmd命令: 一.数据表的导出 1 将数据库TEST完全导出,用户名system 密码manager 导出到D:daoch ...

  9. Java各种排序算法详解

    排序大的分类可以分为两种:内排序和外排序.在排序过程中,全部记录存放在内存,则称为内排序,如果排序过程中需要使用外存,则称为外排序.下面讲的排序都是属于内排序. 内排序有可以分为以下几类: (1).插 ...

  10. 《C#高级编程》学习总结之LINQ

    一.标准的查询操作符 标准查询操作符 说明 Where OfType<TResult> 筛选操作符定义了返回元素的条件. Select SelectMany 投射操作符用于把对象转换为另一 ...