关于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分别是什么,到底有什么区别?本文较长需耐心阅读,基础 ...
随机推荐
- svn 学习
svn命令在linux下的使用 svn命令在linux下的使用SVN软件版本管理 1.将文件checkout到本地目录svn checkout path(path是服务器上的目录)例如:svn che ...
- python ORM理解、元类
元类 参考链接:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00143191 ...
- HNU 12876 Quite Good Numbers 完美数变形
筛法是一种很快的方法,贴代码纪念一下. 做法很像筛法 #include <iostream> #include <cstdio> #include <cstring> ...
- 华为:一张图看懂 HBase
来自为知笔记(Wiz)
- Qt之图形(转换)
简述 QTransform类指定坐标系的2D转换,可以指定平移.缩放.扭曲(剪切).旋转或投影坐标系.绘制图形时,通常会使用. QTransform与QMatrix的不同之处在于,它是一个真正的3x3 ...
- libvirt 部分API 介绍
感谢朋友支持本博客.欢迎共同探讨交流,因为能力和时间有限,错误之处在所难免,欢迎指正! 假设转载,请保留作者信息. 博客地址:http://blog.csdn.net/qq_21398167 原博文地 ...
- POJ 3014:Asteroids(二分匹配,匈牙利算法)
id=3041">Asteroids Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 14399 Acce ...
- Consolas 字体
Consolas是一套等宽字体的字型,属无衬线字体,由Lucas de Groot设计. 概述 这套字型使用了微软的ClearType 字型平滑技术,并随同Windows Vista.Office 2 ...
- Objective-C - NSInteger转换NSString
NSInteger不是对象, 转换为long匹配64位系统, 再组成字符串(%ld). NSString *inStr = [NSString stringWithFormat: @"%ld ...
- WebForms简介
http://www.w3school.com.cn/aspnet/aspnet_intro.asp ASP.NET 是下一代 ASP,不是 ASP 的更新版本. https://docs.micro ...