转载:IO复用\阻塞IO\非阻塞IO\同步IO\异步IO

一、 什么是IO复用?

它是内核提供的一种同时监控多个文件描述符状态改变的一种能力;例如当进程需要操作多个IO相关描述符时(例如服务器程序要同时查看监听socket和大量业务socket是否有数据到来),需要内核能够监控这许多描述符,一旦这些描述符有就绪(或者状态改变了)就告诉主动告诉进程哪些描述符已经就绪,这样站在进程的角度,就不需要挨个的查看每个描述符是否就绪。

二、 IO操作分为两个阶段:

(1)  准备阶段,例如输入操作时要等待数据已经就绪,输出操作时缓冲区中有空间可供使用;

(2)  数据拷贝阶段,例如输入操作时将数据从内核复制到用户缓存,输出操作时将用户缓存复制到内核。

以读取系统调用recvfromfrom为例,每当用户进程发起一个recvfrom操作,站在用户进程的角度,其实它包含上述两个请求:第一个请求就是看看数据是不是准备好了,如果没有准备好就把我阻塞那里(对应阻塞IO)或者给我返回个没有准备好的标志(对应非阻塞IO);第二个请求就是在数据就绪的时候将数据拷贝给用户进程。

三、 Unix环境下有5中IO模型

(1)阻塞IO模型

(2)非阻塞IO模型

(3)IO复用模型

(4)信号驱动IO模型

(5)异步IO模型

其中(1)~(4)都属于同步IO,(5)属于异步IO,因为前4中模型在第一阶段的准备阶段有区别,在第二阶段的数据拷贝过程中都会阻塞用户进程,而(5)在第一阶段的准备阶段和第二阶段的数据拷贝过程都不会阻塞用户进程。

四、各种模型的详细区别

(1)阻塞IO模型

阻塞IO模型中,以数据接收为例,进程调用recvfrom系统调用向内核请求读取数据,其内部过程将如下图1所示:

图1阻塞IO模型

由图1可以看到用户进程从发起recvfrom系统调用开始后的两个阶段都被阻塞。

(2)非阻塞IO模型

以读取数据为例,非阻塞模型中,进程需要先把socket设置为非阻塞模式,这样内核在准备数据时就不会阻塞该系统调用,而是直接返回EWOULDBLOCK,在读取操作时,用户进程一样是调用recvfrom向内核请求数据,其内部过程如下图2所示:

图2 非阻塞模式IO模型

由上图2可以看到非阻塞模式中,在数据准备阶段,系统调用不会被阻塞,但是在数据复制阶段也会被阻塞;因此这里所说的阻塞是指数据准备阶段是否被阻塞,而不是数据拷贝阶段。

(3)IO复用模型

IO复用模型中,进程可以让内核监控多个描述符的就绪状态,一般使用的接口函数为select或者poll,内核通过select查询到所监控的描述符中有就绪的,则把就绪的描述符返回给调用进程,进程再调用recvfrom实际读取数据,其内部过程大致如下图3所示:

图3 、IO复用模型

由上图可以看出,在IO复用模型中,用户进程先调用select或者poll查看是否有数据就绪,如果有数据就绪再调用recvfrom去读取数据,系统在阶段1和阶段2都将会被阻塞,但是阻塞于不同的系统调用(阶段1阻塞于select或者poll,阶段2阻塞于recvfrom)。

(4)信号驱动IO模型

信号驱动IO模型是让内核在描述符就绪时发送SIGIO信号通知用户进程。在使用信号驱动模型进行IO操作时,首先要打开socket使用信号驱动IO的能力;然后调用sigaction系统调用设置信号SIGIO的处理函数,sigaction系统调用不会被阻塞。这样就可以在信号处理函数中读取数据了,其处理过程如下图4所示:

图4 信号驱动IO模型

由上图4可以看出,信号驱动模型只要设置好信号处理函数后就可以进行其他操作了,当有数据到来时内核将会通知进程进行处理;与非阻塞IO模型相比,信号驱动IO模型不需要在准备数据时轮询是否准备好。

(5)异步IO模型

异步IO模型中,用户进程发起读取调用之后会立即返回,待内核接收到数据并将数据拷贝到用户进程空间之后,再通知用户进程,其过程如下图5所示:

图5异步IO模型

五、5中IO模型的比较

上述5中IO操作模型的区别可以参见图6所示:

图6、5中IO模型的比较

同步IO:导致请求进程阻塞,直到IO操作完成;

异步IO:不导致请求阻塞;

因此,前面介绍的5中模型中,前4中IO模型都属于同步IO,因为他们第二阶段的复制数据过程将阻塞用户进程,只有第5种才是真正的异步IO模型。

IO复用\阻塞IO\非阻塞IO\同步IO\异步IO的更多相关文章

  1. 网络编程----堵塞、非堵塞和同步、异步IO

    我是学渣.但我想进步. 本文是面试我的牛人问我的.你知道什么是堵塞.非堵塞和同步.异步IO么?自觉得是分布式系统程序猿的我居然不知道.学习吧. 首先介绍堵塞IO和非堵塞IO: 堵塞IO:是指说程序等待 ...

  2. IO复用,AIO,BIO,NIO,同步,异步,阻塞和非阻塞 区别参考

    参考https://www.cnblogs.com/aspirant/p/6877350.html?utm_source=itdadao&utm_medium=referral IO复用,AI ...

  3. IO复用,AIO,BIO,NIO,同步,异步,阻塞和非阻塞 区别(百度)

    如果面试问到IO操作,这篇文章提到的问题,基本是必问,百度的面试官问我三个问题 (1)什么是NIO(Non-blocked IO),AIO,BIO (2) java IO 与 NIO(New IO)的 ...

  4. IO模型浅析-阻塞、非阻塞、IO复用、信号驱动、异步IO、同步IO

    最近看到OVS用户态的代码,在接收内核态信息的时候,使用了Epoll多路复用机制,对其十分不解,于是从网上找了一些资料,学习了一下<UNIX网络变成卷1:套接字联网API>这本书对应的章节 ...

  5. (转)IO复用,AIO,BIO,NIO,同步,异步,阻塞和非阻塞 区别

    本文来自:https://www.cnblogs.com/aspirant/p/6877350.html?utm_source=itdadao&utm_medium=referral,非常感谢 ...

  6. IO复用,AIO,BIO,NIO,同步,异步,阻塞和非阻塞 区别

    一.什么是socket?什么是I/O操作? 我们都知道unix(like)世界里,一切皆文件,而文件是什么呢?文件就是一串二进制流而已,不管socket,还是FIFO.管道.终端,对我们来说,一切都是 ...

  7. AIO,BIO,NIO,IO复用,同步,异步,阻塞和非阻塞

    (1)什么是NIO(Non-blocked IO),AIO,BIO (2) 区别 (3)select 与 epoll,poll区别 1.什么是socket?什么是I/O操作? 什么是socket? 实 ...

  8. 简述linux同步与异步、阻塞与非阻塞概念以及五种IO模型

    1.概念剖析 相信很多从事linux后台开发工作的都接触过同步&异步.阻塞&非阻塞这样的概念,也相信都曾经产生过误解,比如认为同步就是阻塞.异步就是非阻塞,下面我们先剖析下这几个概念分 ...

  9. IO多路复用,同步,异步,阻塞和非阻塞 区别

    一.什么是socket?什么是I/O操作? 我们都知道unix(like)世界里,一切皆文件,而文件是什么呢?文件就是一串二进制流而已,不管socket,还是FIFO.管道.终端,对我们来说,一切都是 ...

  10. IO多路复用,同步,异步,阻塞和非阻塞 区别(转)

    转自:http://www.cnblogs.com/aspirant/p/6877350.html?utm_source=itdadao&utm_medium=referral 同步.异步 是 ...

随机推荐

  1. Runtime消息动态解析与转发流程

    先上图: 下面根据具体代码看这张图. 一.创建一个Person类, Person.h #import <Foundation/Foundation.h> @interface Person ...

  2. Kotlin入门(6)条件分支的实现

    上一篇文章介绍了字符串的相关操作,其中示例代码用到了if和for语句,表面上看,Kotlin对控制语句的处理与Java很像,可实际上,Kotlin在这方面做了不少的改进,所以本篇和下一篇文章就分别介绍 ...

  3. (其他)最常用的15大Eclipse开发快捷键技巧

    转自CSDNJava我人生(陈磊兴)   原文出处 引言 做java开发的,经常会用Eclipse或者MyEclise集成开发环境,一些实用的Eclipse快捷键和使用技巧,可以在平常开发中节约出很多 ...

  4. 洗礼灵魂,修炼python(44)--巩固篇—反射之重新认识hasattr,gettattr,setattr,delattr

    不急着进入正题.先动手完成一个小程序: 设计一套简单的服务开启关闭程序,每次开启或关闭都得打印服务当前的状态: class Server(object): def __init__(self): se ...

  5. 洗礼灵魂,修炼python(23)--自定义函数(4)—闭包进阶问题—>报错UnboundLocalError: local variable 'x' referenced before assignment

    闭包(lexical closure) 什么是闭包前面已经说过了,但是由于遗留问题,所以单独作为一个章节详解讲解下 不多说,看例子: def funx(x): def funy(y): return ...

  6. mac系统如何在当前目录下打开终端

    给大家推荐一个好用的终端工具 Go2Shell:https://itunes.apple.com/cn/app/go2shell/id445770608?mt=12 在没有这个工具之前 找了好多在当前 ...

  7. Python进阶(一)

    完成慕课网的python基础学习以后,大约花了三天时间,平均每天一个小时,总结了一些比较好的例题和思想方法,下面来学习python进阶吧 参考廖雪峰官方课程 函数 python官方函数调用文档 定义默 ...

  8. File类_常见的方法(获取,创建与删除,判断,重命名)

    获取:  1.1获取文本名称  1.2获取文件路劲  1.3获取文件大小  1.4获取文件修改或创建时间 import java.io.File; import java.text.DateForma ...

  9. 【转】理解js中的原型链,prototype与__proto__的关系

    说到prototype,就不得不先说下new的过程. 我们先看看这样一段代码: 1 <script type="text/javascript"> 2 var Pers ...

  10. MetaMask/metamask-extension/mascara 的运行实现

    https://github.com/MetaMask/metamask-extension/tree/develop/mascara 找了很多个实例,基本上很少是不使用线上钱包的,只有metamas ...