一个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. JavaScript面向对象之我见

    序言 在JavaScript的大世界里讨论面向对象,都要提到两点:1.JavaScript是一门基于原型的面向对象语言 2.模拟类语言的面向对象方式.对于为什么要模拟类语言的面向对象,我个人认为:某些 ...

  2. Hadoop学习笔记—18.Sqoop框架学习

    一.Sqoop基础:连接关系型数据库与Hadoop的桥梁 1.1 Sqoop的基本概念 Hadoop正成为企业用于大数据分析的最热门选择,但想将你的数据移植过去并不容易.Apache Sqoop正在加 ...

  3. .Net开发笔记(十七) 应用程序扩展

    在很多场合,我们需要在已有软件程序上增加一些新的功能,几乎所有原因是因为原有软件功能不能满足我们的需要,我们平时做的插件就属于这种情况,最常见的是VS IDE的插件开发,网上老外写的一篇关于插件开发的 ...

  4. 我的Git手册

    本文肯定不是Git的最佳的教程,它只是本人的Git操作手册,我将从一些实际问题出发,让熟悉SVN用户顺利过度到Git来(当然包括我自己了),其中会加入一些个人感受或看法,相信会对大家有些启发.另外,全 ...

  5. 不要对外公开泛型List成员

    最近在阅读Framework Design Guidelines,本着现学现用的原则,于是就用FxCop工具对代码进行规范性检查时,发现了很多问题,其中包括命名以及一些设计上的规范. 其中,Do no ...

  6. 新版C#编译器关于函数闭包的一处更改

    感谢@DiryBoy的补充,他提到这个问题在MSDN上是有说明的: http://msdn.microsoft.com/en-us/library/vstudio/hh678682.aspx 在Vis ...

  7. 可以这样去理解group by和聚合函数

    写在前面的话:用了好久group by,今天早上一觉醒来,突然感觉group by好陌生,总有个筋别不过来,为什么不能够select * from Table group by id,为什么一定不能是 ...

  8. EntityFramework之数据库以及表基本创建(一)

    前言 之前有学过EF一段时间那时EF才4.0似乎还不太稳定,而现在EF都已7.0版本,同时AspNet Identity都与此大有关联,看来是大势所趋于是开始学习EF,在学EF过程中也遇到一些小问题, ...

  9. Netbeans配置Xdebug

    1.进入 http://xdebug.org/wizard.php 页面,新建一个php页面,里面输入 echo phpinfo(); 然后在运行的页面,复制页面内容到里面, 这个网站会分析出,当前运 ...

  10. Rust初步(四):在rust中处理时间

    这个看起来是一个很小的问题,我们如果是在.NET里面的话,很简单地可以直接使用System.DateTime.Now获取到当前时间,还可以进行各种不同的计算或者输出.但是这样一个问题,在rust里面, ...