IO并发原理 BIO,NIO与AIO

并发原理:

几乎所有的IO接口都是阻塞型的,处理过程中线程将被阻塞,无法进行任何操作直到返回调用结果,或超时。

 

IO模型:系统内核   和   一个调用这个IO的线程

第一步  等待数据准备

第二步  将数据从内核拷贝到进程中

 

BIO  传统阻塞IO

用户线程发送IO请求(read操作)到系统内核,系统内核首先进行数据准备,然后进行数据拷贝。这两个过程中用户线程是完全阻塞的状态,啥也干不了。

用户线程发出IO请求,系统内核会开始准备数据并且直接返回一个error,然后用户线程接收到返回值可以非阻塞(干别的了)。然后用户线程不断地发送请求,时刻询问,如果系统内核没准备好就还是返回error,如果准备好就直接拷贝数据,拷贝过程中是阻塞的。

 

多路复用IO  也就是NIO,非阻塞IO

多了一个select,用来实时监听多个socket是否准备好。当任意socket准备好了 select就会返回,用户就会调用read,系统进行拷贝工作。

优点:select只占用单线程,不消耗太多资源,可以同时处理多个连接

 

异步IO   也就是AIO,异步IO

用户线程发出IO请求后,系统内核接收到请求会立刻给个返回,使用户线程不会阻塞。

然后系统内核自己等待数据准备,然后拷贝到用户内存,完成后通知一下用户线程。

 

举个实际场景的例子 分析一下什么是BIO,NIO,AIO?


BIO:小明坐在家里想打LOL,但是电脑正被他爹占着敲代码.. 这时候小明只能是阻塞的等待他爹改完bug 才能用电脑打游戏(没招)。小明就在他爹旁边干等着改BUG。

NIO,非阻塞IO: 小明觉得干等着太难受了,还耽误时间,就决定先去看电视 边看电视边等,看会电视回来问问他爹改完BUG了吗。小明非阻塞在他爹旁边

AIO,异步IO:  小明很生气,就坐客厅看电视去了,让他爹改好了BUG直接告诉他,省着他老来问了。异步IO

 

 

非阻塞 IO 的核心在于使用一个 Selector 来管理多个通道,可以是 SocketChannel,也可以是 ServerSocketChannel,将各个通道注册到 Selector 上,指定监听的事件。

之后可以只用一个线程来轮询这个 Selector,看看上面是否有通道是准备好的,当通道准备好可读或可写,然后才去开始真正的读写,这样速度就很快了。我们就完全没有必要给每个通道都起一个线程。

NIO 中 Selector 是对底层操作系统实现的一个抽象,管理通道状态其实都是底层系统实现的,这里简单介绍下在不同系统下的实现。

 

select:上世纪 80 年代就实现了,它支持注册 FD_SETSIZE(1024) 个 socket,在那个年代肯定是够用的,不过现在嘛,肯定是不行了。

poll:1997 年,出现了 poll 作为 select 的替代者,最大的区别就是,poll 不再限制 socket 数量。

select 和 poll 都有一个共同的问题,那就是它们都只会告诉你有几个通道准备好了,但是不会告诉你具体是哪几个通道。所以,一旦知道有通道准备好以后,自己还是需要进行一次扫描,显然这个不太好,通道少的时候还行,一旦通道的数量是几十万个以上的时候,扫描一次的时间都很可观了,时间复杂度 O(n)。所以,后来才催生了以下实现。

epoll:2002 年随 Linux 内核 2.5.44 发布,epoll 能直接返回具体的准备好的通道,时间复杂度 O(1)。

 

 

 

 CPU从磁盘数据读取过程 https://www.cnblogs.com/ttaall/p/13738562.html

 传统IO与零拷贝的几种实现 https://www.cnblogs.com/ttaall/p/14029974.html

 图解计算机底层IO过程及JavaNIO https://www.cnblogs.com/ttaall/p/14128788.html

posted @ 2019-12-09 20:03  六小扛把子  阅读(710)  评论(0编辑  收藏  举报