乱弹 --- Linux 之 I/O模型

随着现在互联网技术的发展,在以前对一个网站的要求都不高,但是现在要求越来越高了,不断的优化服务,不断的提高硬件设施,在以前I/O方面的消耗还影响不大,但是现在I/O的瓶颈越来越凸显,了解I/O模型,能了解I/O的发展历史,同时也能帮助我们写出更加健壮的代码。

一般来说,I/O模型可以分为阻塞/非阻塞和同步/异步,我们先从阻塞/非阻塞模型说起。

同步阻塞I/O

用户进程发起I/O操作后,需要等待其操作完成才能继续运行。阻塞一词可以理解为等待,具体什么等待呢?— 用户等待,用户一旦发起一个阻塞I/O,那么用户就需要等待内核把数据准备好,只有内核数据准备好了后,用户才读写数据然后继续往下执行。
阻塞IO的编程模型非常易于理解,但性能却并不理想,它会造成CPU的大量闲置(注意这里的CPU闲置指的是用户CPU时间)。使用阻塞IO开发的系统吞吐量会比较低。虽然可以优化为每一次 Socket 请求使用独立的线程,但会造成线程膨胀,使系统越来越慢,当达到一定的并发后,服务器最终会宕机。通过线程池可以控制系统创建线程的数量,但是毕竟用了很多的线程来提高吞吐量,但是随着线程的增多,线程的开销也会越来越大,因此仍然无法做到系统性能的最优。

同步阻塞 I/O 模型的典型流程:
这里写图片描述
注:部分图片引自 使用异步 I/O 大大提高应用程序的性能

同步非阻塞I/O

用户进程发起I/O操作后,无需等待内核IO操作完成(这里的等待是用户线程等待),可继续做其它事情,但是用户进程需要不断的询问I/O操作是否就绪,因为内核不会通知用户线程数据已经准备好了,需要用户线程主动的去判断,阻塞I/O也需要主动的等待数据,只是在等待的过程中,不能干其它的事情,而非阻塞I/O在等待内核数据的同时可以去干其它的事情,当询问得知数据准备好了后,再去读取数据,但是用户线程也不知道什么时候数据准备好了,因此需要不断去问内核数据是否准备就绪,因此不停轮询会略微增加额外的CPU资源浪费。

同步非阻塞 I/O 模型的典型流程:
这里写图片描述

异步阻塞I/O

用户进程发起I/O操作后,不等待内核 IO 操作的完成,等内核完成 IO 操作以后会通知应用程序,这其实就是同步和异步最关键的区别,同步必须等待或者主动的去询问 IO 是否完成,那么为什么说是阻塞的呢?因为用户发起的调用是阻塞的。

异步阻塞 I/O 模型的典型流程 (以select为例):
这里写图片描述

异步非阻塞I/O

用户进程只需要发起一个 IO 操作然后立即返回,等 IO 操作真正的完成以后,应用程序会得到 IO 操作完成的通知,此时用户进程只需要对数据进行处理就好了,不需要进行实际的 IO 读写操作,因为 真正的 IO读取或者写入操作已经由 内核完成了。
异步非阻塞 I/O 模型的典型流程:
这里写图片描述

Java中的I/O

Java对于IO的封装分为BIO、NIO和AIO。Java目前并不支持异步IO,BIO对应的是同步阻塞IO,NIO和AIO对应的都是同步非阻塞IO。

java nio的io模型是同步非阻塞(基于事件驱动机制,感觉像异步),这里的同步异步指的是用户进程是否需要参与IO,很明显 目前 java 中的nio 都需要自己去read 数据。

java nio提供了异步处理,这个异步指的内核准备好数据后通知用户进程,然后用户进程再继续处理,因此从这方面看是异步的,它对IO的读写还是同步阻塞的。只是通过线程复用,将IO的准备时间分离出来。

BIO

Java中的BIO对应的是同步阻塞IO。 BIO的服务器实现模式为一个连接分配一个线程,服务端的线程个数和客户端并发访问数呈正比,随着访问量的增加会迅速导致线程数量膨胀,最终导致系统性能的急剧下降。可以通过使用线程池实现一个线程处理多个客户端的模型,但开启线程的数量终归会受到系统资源的限制,而且频繁的线程上下文切换也会导致CPU的利用率不高。

NIO

JDK 1.4中的java.nio.*包中引入了全新的Java I/O类库,与之相对应的是同步非阻塞IO。相比于BIO,NIO的性能实现了质的提升,它适用于连接数目多且连接比较短的轻量级操作架构。

AIO

NIO.2虽然在2003年的JSR 203就已经提出,但直到2011年才于JDK 7中实现并一同发布。它提供了更多的文件系统操作API以及文件的异步IO操作,即AIO。由于每个操作系统AIO对应的实现方式都不同,因此Java做了封装。Linux系统中2.6内核及其以上对应的是epoll,低版本仍然对应poll,Windows系统也有相应的IOCP的系统级支持。由于Java的服务端程序很少将Windows系统作为生产服务器,因此Linux系统的I/O模型更加受到关注。我们看到,在Linux系统上,Java实际并未真正使用异步IO,而是非阻塞IO,AIO虽然封装的更好,模拟成为了异步IO的样子,但是其本质仍然是poll或epoll这样的同步IO。

Linux I/O 模型

阻塞IO

基本描述同上

非阻塞IO

基本描述同上

IO复用

Linux提供select/poll,进程通过将一个或多个fd传递给select或poll系统调用,阻塞在select操作上,这样,select/poll可以帮我们侦测多个fd是否处于就绪状态。

select/poll是顺序扫描fd是否就绪,而且支持的fd数量有限,因此它的使用受到了一些制约。

Linux还提供一个epoll系统调用,epoll使用基于事件驱动方式代替顺序扫描,因此性能更高。当有fd就绪时,返回需要处理的事件,而不需要像select 遍历所有的fd那样。

epoll支持两种触发模式:边沿触发方式,水平触发模式(默认)
为了更好的理解这两种触发模式,考虑下面场景:
(1)客户端发来100字节的数据
(2)服务器调用epoll_wait后,发现套接字可读,于是读取了50字节,则在服务器套接字接收缓存中还有50字节未读,
(3)当服务器再次执行epoll_wait后,如果是边沿触发,则尽管接收缓存中还有50字节数据未读,则再次调用epoll_wait后,epoll_wait将不再返回该套接字可读,反之,若服务器工作于水平触发模式,则因为套接字缓存中有数据可读,所以当再次调用epoll_wait后,将仍可以返回此套接字为可读状态,因此边沿触发只发生在状态改变的那一时刻,而对于水平触发,只要套接字可读写,epoll_wait就立即返回。

信号驱动IO

我们可以使用信号,来告诉内核当数据准备就绪的时候,使用SIGIO信号来通知我们。我们将此称为信号驱动的I/O

异步IO

通知内核启动某个操作,并让内核在整个操作完成后(包括数据的复制)通知用户进程。
信号驱动I/O模型通知的是何时可以开始一个I/O操作,异步I/O模型有内核通知I/O操作何时已经完成

参考

使用异步 I/O 大大提高应用程序的性能

聊聊Linux 五种IO模型

linux中的“5种网络 IO 模型”

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REaDME.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 、资源1项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值