当前位置: 首页 > news >正文

BIO,NIO,AIO,多路复用IO?

原文链接:https://blog.csdn.net/historyasamirror/article/details/5778378

1. 什么是IO?

在计算机系统中I/O就是输入(Input)和输出(Output)的意思,只要具有输入输出类型的交互系统都可以认为是I/O系统。

2. 如何理解IO过程?

对于一个network IO (这里我们以read举例),它会涉及到两个系统对象,一个是调用这个IO的进程(process )(or thread),另一个就是系统内核(kernel)。当一个read操作发生时,它会经历两个阶段:

  1. 进程调用系统内核并等待数据准备 (Waiting for the data to be ready)
  2. 系统内核准备好数据,将数据从内核拷贝到进程中 (Copying the data from the kernel to the process)
    记住这两点很重要,因为这些IO Model的区别就是在两个阶段上各有不同的情况。
  1. **BIO (Blocking I/O): 同步阻塞I/O模式,数据的读取写入必须阻塞在一个线程内等待其完成。**当用户进程调用了recvfrom这个系统调用,kernel就开始了IO的第一个阶段:准备数据。对于network io来说,很多时候数据在一开始还没有到达(比如,还没有收到一个完整的UDP包),这个时候kernel就要等待足够的数据到来。而在用户进程这边,整个进程会被阻塞。当kernel一直等到数据准备好了,它就会将数据从kernel中拷贝到用户内存,然后kernel返回结果,用户进程才解除block的状态,重新运行起来。所以,blocking IO的特点就是在IO执行的两个阶段都被block了。

同步阻塞I/O模型.png-31.4kB

  1. NIO (New I/O): NIO是一种同步非阻塞的I/O模型,在Java 1.4 中引入了NIO框架,对应 java.nio 包,提供了 Channel , Selector,Buffer等抽象。NIO中的N可以理解为Non-blocking,不单纯是New。它支持面向缓冲的,基于通道的I/O操作方法。 NIO提供了与传统BIO模型中的 SocketServerSocket 相对应的 SocketChannelServerSocketChannel 两种不同的套接字通道实现,两种通道都支持阻塞和非阻塞两种模式。阻塞模式使用就像传统中的支持一样,比较简单,但是性能和可靠性都不好;非阻塞模式正好与之相反。对于低负载、低并发的应用程序,可以使用同步阻塞I/O来提升开发速率和更好的维护性;对于高负载、高并发的(网络)应用,应使用 NIO 的非阻塞模式来开发。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F9Oqg3he-1596613668518)(http://static.zybuluo.com/rainybowe/0agaz3rfsrlgxr5b5jtt4k1c/%E6%9C%AA%E5%91%BD%E5%90%8D%E6%96%87%E4%BB%B6%20(1)].png)

  1. AIO (Asynchronous I/O): AIO 也就是 NIO 2。在 Java 7 中引入了 NIO 的改进版 NIO 2,它是异步非阻塞的IO模型。异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。AIO 是异步IO的缩写,虽然 NIO 在网络操作中,提供了非阻塞的方法,但是 NIO 的 IO 行为还是同步的。对于 NIO 来说,我们的业务线程是在 IO 操作准备好时,得到通知,接着就由这个线程自行进行 IO 操作,IO操作本身是同步的。查阅网上相关资料,我发现就目前来说 AIO 的应用还不是很广泛,Netty 之前也尝试使用过 AIO,不过又放弃了。
未命名文件 (2).png-33.2kB
  1. **IO多路复用(IO multiplexing)IO multiplexing这个词可能有点陌生,但是如果我说select,epoll,大概就都能明白了。有些地方也称这种IO方式为event driven IO。我们都知道,select/epoll的好处就在于单个process就可以同时处理多个网络连接的IO。**它的基本原理就是select/epoll这个function会不断的轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程。

    当用户进程调用了select,那么整个进程会被block,而同时,kernel会“监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用read操作,将数据从kernel拷贝到用户进程。
    这个图和blocking IO的图其实并没有太大的不同,事实上,还更差一些。因为这里需要使用两个system call (select 和 recvfrom),而blocking IO只调用了一个system call (recvfrom)。但是,用select的优势在于它可以同时处理多个connection。(多说一句。所以,如果处理的连接数不是很高的话,使用select/epoll的web server不一定比使用multi-threading + blocking IO的web server性能更好,可能延迟还更大。select/epoll的优势并不是对于单个连接能处理得更快,而是在于能处理更多的连接。
    在IO multiplexing Model中,实际中,对于每一个socket,一般都设置成为non-blocking,但是,如下图所示,整个用户的process其实是一直被block的。只不过process是被select这个函数block,而不是被socket IO给block。

I/O复用模型详解(网络总结)

附区别对比1:

2

附区别对比2:

img

相关文章:

  • 【Web API系列教程】3.4 — 实战:处理数据(处理实体关系)
  • 输出由几个无重复数字组成的三位数(内测第0届第3题)
  • 讲一下线程和进程的区别和联系?
  • 正则
  • 讲一下线程状态并且解释一下?
  • windows 和 linux ssh互连
  • 【代码规范】
  • 【程序员眼中的统计学(12)】相关与回归:我的线条如何? (转)
  • 讲一下进程间通讯方式?
  • Docker的文件系统
  • 信号和信号量有什么区别?
  • 进程的调度算法有哪些?
  • ORA-00604 ORA-14452 ORA-20783
  • 线程同步的四种方式
  • 2015年小结
  • 2017-09-12 前端日报
  • Dubbo 整合 Pinpoint 做分布式服务请求跟踪
  • ESLint简单操作
  • JavaScript中的对象个人分享
  • JS专题之继承
  • MySQL QA
  • SpringCloud集成分布式事务LCN (一)
  • 初探 Vue 生命周期和钩子函数
  • 解决iview多表头动态更改列元素发生的错误
  • 码农张的Bug人生 - 初来乍到
  • 前言-如何学习区块链
  • 设计模式走一遍---观察者模式
  • 好程序员web前端教程分享CSS不同元素margin的计算 ...
  • #if和#ifdef区别
  • #微信小程序(布局、渲染层基础知识)
  • (C++)八皇后问题
  • (C++17) std算法之执行策略 execution
  • (动态规划)5. 最长回文子串 java解决
  • (分布式缓存)Redis哨兵
  • (附源码)ssm教师工作量核算统计系统 毕业设计 162307
  • (三)uboot源码分析
  • (三)终结任务
  • (小白学Java)Java简介和基本配置
  • (原创)Stanford Machine Learning (by Andrew NG) --- (week 9) Anomaly DetectionRecommender Systems...
  • (转)程序员技术练级攻略
  • ****** 二十三 ******、软设笔记【数据库】-数据操作-常用关系操作、关系运算
  • .mysql secret在哪_MYSQL基本操作(上)
  • .NET Reactor简单使用教程
  • .Net Remoting常用部署结构
  • .net 按比例显示图片的缩略图
  • .netcore 如何获取系统中所有session_如何把百度推广中获取的线索(基木鱼,电话,百度商桥等)同步到企业微信或者企业CRM等企业营销系统中...
  • .NET连接数据库方式
  • :中兴通讯为何成功
  • @Autowired标签与 @Resource标签 的区别
  • @Not - Empty-Null-Blank
  • [ Linux ] Linux信号概述 信号的产生
  • [acwing周赛复盘] 第 94 场周赛20230311
  • [Angular] 笔记 18:Angular Router
  • [BUG] Authentication Error
  • [C++] 默认构造函数、参数化构造函数、拷贝构造函数、移动构造函数及其使用案例