文章目录
背景
Unix I/O模型
I/O模型一共有哪些策略,JavaI/O是对这些策略的具体实现
阻塞I/O模型
第一阶段copy阻塞,第二阶段copy阻塞;
- 进程在整个recvfrom期间阻塞,即recvfrom没完成前,进程都处于阻塞状态,等待I/O资源,等到了,再继续执行。
非阻塞I/O模型
第一阶段copy不阻塞,但轮询,第二阶段copy阻塞;
recvfrom从应用层到达内核的时候,如果该缓冲区没有数据的话,就直接返回一个EWOULDBLOCK错误,一般都对非阻塞I/O模型进行轮询检查这个状态,看内核是不是有数据到来。
虽然第一个copy进程不阻塞,采用轮询的方式等待内核缓冲区有数据,但进程也只是原地自旋,也没执行别的,和阻塞区别不大,没提高多少性能;
I/O多路复用模型
第一阶段copy阻塞(阻塞在select操作上),第二阶段copy阻塞(和上面两个I/O模型一样,阻塞发生在recvfrom上);
I/O多路复用技术
在并发情况下,多个线程因I/O操作阻塞,现在创建一个线程,发起一次select调用,只阻塞这一个线程,这个线程又可以监控多个文件,从而一个阻塞的线程支持并发---------即,一个线程解决并发的问题。
- select缺点:线性扫描全部socket,但只有少数的socket活跃,所以花费在不活跃的socket上的扫描时间白白浪费,随着socket FD越多,效率越低;
信号驱动I/O模型
第一阶段copy不阻塞,第二阶段copy阻塞;
异步I/O模型
告知内核启动某个操作,并让内核在整个操作完成后(包括将数据从内核复制到用户自己的缓冲区)通知我们。
这种模型与信号驱动模型的主要区别
是:
- 信号驱动I/O由内核通知我们何时开始一个I/O操作;
【即,第一个阶段copy是不阻塞的,当第一个阶段copy完成(即将数据从外部复制到内核缓冲区),内核通知进程开始第二个阶段copy(将数据从内核缓冲区复制到用户缓冲区),即开始一个I/O操作】 - 异步I/O模型由内核通知我们I/O操作何时已经完成。
【信号驱动I/O,第二个阶段copy阻塞,异步I/O模型两个阶段copy都不阻塞,进程继续执行,等数据copy完成,再通知进程处理数据】
开始时,进程调用aio_read系统调用进行异步调用,此时两个阶段异步进行,都不阻塞(由内核处理),进程继续执行,等数据准备好(从外部复制到内核数据库,再复制到用户缓冲区),通知进程,进程就可以执行用户缓冲区中的数据了
五种I/O模型的比较
Java IO模型
IO(面向流的,也叫BIO)
在1.4之前,Java只提供了一种IO模型,即阻塞式IO模型(BIO)。
- 红色:低级流;
直接连接到设备(磁盘(文件),网卡(网络I/O))上读取;效率低; - 蓝色:高级流;
不直接连接设备,而是接入对应低级流上,进行读取;
NIO
Buffer
- 创建buffer,capacity和limit一开始指向,创建容量(eg:8)的后一个
- flip准备读:将position移到数据前面,开始读;limit移到读入数据的后面,防止读到界外;
- clear:清除的时候,并不删除数据,而是将position移到前面,读的时候覆盖原数据;
Channel
- Channel接到buffer上读取里面的数据
Selector
-
概述
-
Selector是抽象类
-
和select()相关的方法
NIO2(AIO)
- 概述
- 使用步骤【了解】