关于Blocking IO,non-Blokcing IO,async IO的区别和理解
来源:http://shmilyaw-hotmail-com.iteye.com/blog/1896683
概括来说,一个IO操作可以分为两个部分:发出请求、结果完成。如果从发出请求到结果返回,一直Block,那就是Blocking IO(常见的顺序化程序结构);如果发出请求就可以返回(结果完成不考虑),就是non-blocking
IO;如果发出请求就返回,结果返回是Block在select或者poll上的,则其只能称为IO multiplexing;如果发出请求就返回,结果返回通过Call Back的方式被处理,就是AIO。
文[2]中图画的不错,说的也比较清楚借来用一下。
Blocking IO
先从这个开始讨论起,在前面的文章里,我们知道一个server端的程序要和一个客户端通信,它首先自己要绑定到一个端口,然后调用accept方法来接收一个客户端的请求并建立连接。这个accept返回的socket连接可以获取到双方通信的InputStream和OutputStream,这样双方就可以通过这两个Stream来互相发消息了。
当然,对于单独的一个server进程和一个client进程来说,这是一个典型的场景。但是如果对于有多个client的情况下,我们该怎么来处理呢?一种典型的思路就是,我们针对每一个client连接请求建立一个thread来处理。这种模式如下图:

按照这种思路,针对每一个client,我们都有一个对应的handler来处理他们的业务逻辑。每个handler对应一个线程。
我们再想想,在有大量用户连接的情况下,server将针对所有连接client创建thread。如果有成千上万的连接的话,这将是一个很大的开销。由于系统资源实际的限制,可能会占用大量的资源甚至会导致资源被消耗光的情况。另外,这么多个线程连接需要处理,CPU需要在多个线程之间切换。在大量线程的情况下,切换的开销也很大。在这些情况下,请求量大的时候系统的性能和资源利用率都不高。那么我们有没有什么办法可以提高资源利用率和性能呢?
Non-Blocking IO
除了前面提到的blocking IO,其实还有一种io的方式,就是Non-Blocking IO。在详细讨论Non-Blocking IO之前,我们先看看原来blocking IO的一些不足。我们前面的每个连接一个线程的方式如下图所示:

对于每一个连接的所有操作,从建立连接,准备数据,读取数据,编码,解码以及来回发送数据,都在一个线程里全包了。之所以会出现前面提到的资源利用率不高和系统性能受到影响,就是因为通过socket进行io的系统性能和系统本身进程性能本身是有大的差异的。一般来说,IO的性能比系统CPU的性能要差几个数量级。所以才会有大量线程要处理数据的时候,都卡在这里等IO了。这就是前面这种方式有问题的根源所在了。
那么,我们有没有什么办法可以改进一下呢?我们这个时候可以考虑一下异步程序执行的思路。一般对于异步程序执行来说,在调用某一个方法的时候,这个被调用的方法在另外的一个进程或者线程中执行。这个调用方法的进程并不等被调用的方法返回结果,而是继续执行自己后面的过程。可是,在调用的目标方法结束之后,我们怎么让这个调用方法的进程知道方法执行结束了并知道方法的结果呢?这个时候,我们很多时候会使用一种回调的机制。关于回调机制的思路,和我前面一篇讨论Observer模式的文章说的非常近似。笼统的来说,就是我这个调用方法的进程实现注册好了一个通知的机制,然后在被调用方法结束后,这个被调用的方法进程通过这个机制来通知我。
如果我们借鉴这个思路,比如说前面有一些客户端连接服务器端,它们只需要把要操作的目的资源,比如写某个文件之类的,针对哪个socket等等关联起来。等一旦socket连接准备好了再触发它们。这样就不需要开这么多个线程来等了。这些socket连接ready等行为相当于一个定义的一个事件被触发了。我们很多要被回调的方法都放在一个事件通知的队列里。这些回调事件的执行可以放到单独的一个线程里执行。这样也就不需要前面那么多的线程,也减少了线程间切换的开销。
Blocking IO
这个最好理解了,在Blocking IO模式下,函数调用只有在操作完成后才会返回。下图是它调用过程的图示:

重点解释下上图,下面例子都会讲到。首先application调用 recvfrom()转入kernel,注意kernel有2个过程,wait for data和copy data from kernel to user。直到最后copy complete后,recvfrom()才返回。此过程一直是阻塞的。
Non-Blocking IO
Non-Blocking 是Blocking的反,也就是说,即使操作没有完成,函数也可以返回。调用过程如下:

可以看见,如果直接操作它,那就是个轮询。。直到内核缓冲区有数据
AIO也是这样啊?对!这是Non-Blocking IO 和AIO的共同点。其实从概念层面来说Non-Blocking IO 就是AIO,他们没有什么区别。但是Non-Blocking IO是对文件描述符(*nix)或者Handle(Windows)的设置,在执行操作时不需要特殊的数据结构。Non-Blocking
IO提交请求后只能通过提交的操作函数来查询操作是否完成,这是一个很大的限制。而AIO往往会提供多种通知或者查询机制,也就是说用Non-Blocking IO时只能轮询,而AIO有更多选择(其它通知机制)。所以是否支持轮询外的其他机制是AIO和Non-Blocking
IO的区别。
I/O multiplexing (select and poll)
最常见的I/O复用模型,select。

select先阻塞,有活动套接字才返回。与blocking I/O相比,select会有两次系统调用,但是select能处理多个套接字。
关于Blocking IO,non-Blokcing IO,async IO的区别和理解的更多相关文章
- Async IO
I was recently reading a series on “Write Sequential Non-Blocking IO Code With Fibers in NodeJS” by ...
- 一款DMA性能优化记录:异步传输和指定实时信号做async IO
关键词:DMA.sync.async.SIGIO.F_SETSIG. DMA本身用于减轻CPU负担,进行CPU off-load搬运工作. 在DMA驱动内部实现有同步和异步模式,异步模式使用dma_a ...
- [Functional Programming] Async IO Functor
We will see a peculiar example of a pure function. This function contained a side-effect, but we dub ...
- System.IO.Pipelines: .NET上高性能IO
System.IO.Pipelines是一个新的库,旨在简化在.NET中执行高性能IO的过程.它是一个依赖.NET Standard的库,适用于所有.NET实现. Pipelines诞生于.NET C ...
- 《Linux/UNIX系统编程手册》第63章 IO多路复用、信号驱动IO以及epoll
关键词:fasync_helper.kill_async.sigsuspend.sigaction.fcntl.F_SETOWN_EX.F_SETSIG.select().poll().poll_wa ...
- 同步IO与同步非阻塞IO的理解
本文图片均来自网络 一.同步IO---Blocking IO 在Blocking IO模型中,用户空间的应用程序执行一个系统调用(recvform),这会导致应用程序阻塞,直到数据准备好,并且将数据从 ...
- IO模型《六》IO模型比较分析
IO模型比较分析 到目前为止,已经将四个IO Model都介绍完了.现在回过头来回答最初的那几个问题:blocking和non-blocking的区别在哪,synchronous IO和asynchr ...
- IO模型《一》IO模型介绍
IO模型介绍 为了更好地了解IO模型,我们需要事先回顾下:同步.异步.阻塞.非阻塞 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞 ...
- IO - 同步 异步 阻塞 非阻塞的区别,学习Swoole有帮助
同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?本文较长需耐心阅读,基础 ...
随机推荐
- 守护、互斥锁、IPC和生产者消费者模型
守护进程 主进程创建守护进程 其一:守护进程会在主进程代码执行结束后就终止 其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes are ...
- fuser ---显示出当前程序使用磁盘上的某个文件
fuser 可以显示出当前哪个程序在使用磁盘上的某个文件.挂载点.甚至网络端口,并给出程序进程的详细信息. fuser只把PID输出到标准输出,其他的都输出到标准错误输出. a 显示所有命令行中指定的 ...
- 紫书 例题 10-7 UVa 10820 (欧拉函数)
这道题要找二元组(x, y) 满足1 <= x, y <= n 且x与y互素 那么我就可以假设x < y, 设这时答案为f(n) 那么答案就为2 * f(n) +1(x与y反过来就乘 ...
- Zookeeper入门-Java版本HelloWorld例子
上一篇介绍了,Zookeeper的基本概念,怎么启动,怎么解决可能遇到的几个问题.本篇,根据网上代码,整理了一个例子,Zookeeper的HelloWorld. 下面这个代码,还是比较简单的,核心类就 ...
- 【Codeforces Round #462 (Div. 1) B】A Determined Cleanup
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 设\(设f(x)=a_d*x^{d}+a_{d-1}*x^{d-1}+...+a_1*x+a_0\) 用它去除x+k 用多项式除法除 ...
- 大话设计模式C++实现-第15章-抽象工厂模式
一.UML图 二.概念 抽象方法模式(Abstract Factory):提供一个创建一系列相关或互相依赖对象的接口,而无需指定他们详细的类. 三.包括的角色 (1)抽象工厂 (2)详细工厂:包含详细 ...
- DevExpress控件的安装及画图控件的使用
近期须要绘制纵断面图,而AE自带的又不是非常好,查找资料后使用DevExpress控件中的画图控件实现了纵断面的绘制.Dev控件是须要付费的.这里我们使用破解版的哈. 安装包及破解文件上传至我的网盘了 ...
- Spring MVC 待学习---新特性
Spring3.1新特性 一.Spring2.5之前,我们都是通过实现Controller接口或其实现来定义我们的处理器类. 二.Spring2.5引入注解式处理器支持,通过@Controller ...
- Hadoop的多节点集群详细启动步骤(3或5节点)
版本1 利用自己写的脚本来启动,见如下博客 hadoop-2.6.0-cdh5.4.5.tar.gz(CDH)的3节点集群搭建 hadoop-2.6.0.tar.gz的集群搭建(3节点) hadoop ...
- Android App中使用Gallery制作幻灯片播放效果
http://www.jb51.net/article/83313.htm 我们有时候在iPhone手机上或者Windows上面看到动态的图片,可以通过鼠标或者手指触摸来移动它,产生动态的图片滚动效果 ...