多线程隙-IO模型(BIO、NIO、AIO)

同步,异步 和 阻塞,非阻塞之间的区别?

同步,异步,是描述被调用方的。阻塞,非阻塞,是描述调用方的。 同步不一定阻塞,异步也不一定非阻塞。没有必然关系。
举个简单的例子:
1 老张把水壶放到火上,一直在水壶旁等着水开。(同步阻塞) 
2 老张把水壶放到火上,去客厅看电视,时不时去厨房看看水开没有。(同步非阻塞)
 3 老张把响水壶放到火上,一直在水壶旁等着水开。(异步阻塞) 
4 老张把响水壶放到火上,去客厅看电视,水壶响之前不再去看它了,响了再去拿壶。(异步非阻塞) 1和2的区别是,调用方在得到返回之前所做的事情不一行。 1和3的区别是,被调用方对于烧水的处理不一样。

BIO(Blocking IO):

同步并阻塞,服务器实现方式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理。
在使用同步I/O的网络应用中,如果要同时处理多个客户端请求,或是在客户端要同时和多个服务器进行通讯,就必须使用多线程来处理。也就是说,将每一个客户端请求分配给一个线程来单独处理。这样做虽然可以达到我们的要求,但同时又会带来另外一个问题。由于每创建一个线程,就要为这个线程分配一定的内存空间(也叫工作存储器),而且操作系统本身也对线程的总数有一定的限制。如果客户端的请求过多,服务端程序可能会因为不堪重负而拒绝客户端的请求,甚至服务器可能会因此而瘫痪。

NIO(Non-Blocking IO):

非阻塞IO,将阻塞变为非阻塞,那就是用户进程在发起系统调用时指定为非阻塞,内核接收到请求后,就会立即返回,然后用户进程通过轮询的方式来拉取处理结果

非阻塞IO虽然相对于阻塞IO大幅提升了性能,但依旧不是完美的解决方案,其依然存在性能问题,也就是频繁的轮询导致频繁的系统调用,会耗费大量的CPU资源。比如当并发很高时,假设有1000个并发,那么单位时间循环内将会有1000次系统调用去轮询执行结果,而实际上可能只有2个请求结果执行完毕,这就会有998次无效的系统调用,造成严重的性能浪费。有问题就要解决,那NIO问题的本质就是频繁轮询导致的无效系统调用。

IO多路复用:

客户端发送请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。

IO多路复用之select/poll:

Select是内核提供的系统调用,它支持一次查询多个系统调用的可用状态,当任意一个结果状态可用时就会返回,用户进程再发起一次系统调用进行数据读取。换句话说,就是NIO中N次的系统调用,借助Select,只需要发起一次系统调用就够了。但是,select有一个限制,就是存在连接数限制,针对于此,又提出了poll。其与select相比,主要是解决了连接限制。
select/poll 虽然解决了NIO重复无效系统调用用的问题,但同时又引入了新的问题。问题是:
用户空间和内核空间之间,大量的数据拷贝
内核循环遍历IO状态,浪费CPU时间
换句话说,select/poll虽然减少了用户进程的发起的系统调用,但内核的工作量只增不减。在高并发的情况下,内核的性能问题依旧。所以select/poll的问题本质是:内核存在无效的循环遍历。

IO多路复用之epoll:

针对select/pool引入的问题,我们把解决问题的思路转回到内核上,如何减少内核重复无效的循环遍历呢?变主动为被动,基于事件驱动来实现。

AIO:

与NIO不同,当进行读写操作时,只须直接调用API的read或write方法即可。这两种方法均为异步的,对于读操作而言,当有流可读取时,操作系统会将可读的流传入read方法的缓冲区,并通知应用程序;对于写操作而言,当操作系统将write方法传递的流写入完毕时,操作系统主动通知应用程序。 即可以理解为,read/write方法都是异步的,完成后会主动调用回调函数。

BIO、NIO、AIO适用场景分析:

BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。•NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。•AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。

参考:
https://www.bilibili.com/video/BV1VJ411D7Pm
https://www.jianshu.com/p/0a03c427359a
https://juejin.im/post/6844903812738596878
https://www.jianshu.com/p/511b9cffbdac

posted @ 2021-02-07 16:43  .Neterr  阅读(110)  评论(0编辑  收藏  举报