(一)分类
从载体上:网络IO和文件IO
从类型上:BIO(同步阻塞) ,NIO(同步非阻塞),AIO(异步非阻塞)
注:java中的NIO实际是IO多路复用模型,采用select系统调用
(二)IO模型
(三)IO概述
1、核心概念
read系统调用,是把数据从内核缓冲区复制到进程缓冲区;而write系统调用,是把数据从进程缓冲区复制到内核缓冲区。这个两个系统调用,都不负责数据在内核缓冲区和物理设备(磁盘、网卡)之间的交换。底层的读写交换,是由操作系统kernel内核完成的。
注:socket读写,文件读写在原理和流程上的处理都是相同的,socket读写是网卡和内存的数据读写交互,文件读写是磁盘或外置存储设备和内存的读写交互
2、java网络IO读写流程
3、阻塞、非阻塞和异步、同步的区别
阻塞IO,指的是需要内核IO操作彻底完成后,才返回到用户空间,执行用户的操作。阻塞指的是用户空间程序的执行状态,用户空间程序需等到IO操作彻底完成。传统的IO模型都是同步阻塞IO。在java中,默认创建的socket都是阻塞的。 非阻塞是指用户空间(调用线程)拿到状态就返回,IO操作可以干就干,不可以干,就去干的事情。
同步IO,是一种用户空间与内核空间的调用发起方式。同步IO是指用户空间线程是主动发起IO请求的一方,内核空间是被动接受方。异步IO则反过来,是指内核kernel是主动发起IO请求的一方,用户线程是被动接受方。主要是通过用户空间线程向内核空间注册各种IO时间的回调函数,由内核去主动调用。
(四)IO模型详解
1、同步阻塞IO(BIO)
在阻塞式 I/O 模型中,应用程序在从IO系统调用开始,一直到到系统调用返回,这段时间是阻塞的。返回成功后,应用进程开始处理用户空间的缓存数据。
2、同步非阻塞IO
(1)在内核缓冲区没有数据的情况下,系统调用会立即返回,返回一个调用失败的信息。
(2)在内核缓冲区有数据的情况下,是阻塞的,直到数据从内核缓冲复制到用户进程缓冲。复制完成后,系统调用返回成功,应用进程开始处理用户空间的缓存数据
3、IO复用模型
(1)IO多路复用模型,就是通过一种新的系统调用,一个进程可以监视多个文件描述符,一旦某个描述符就绪(一般是内核缓冲区可读/可写),内核kernel能够通知程序进行相应的IO系统调用。 目前支持IO多路复用的系统调用,有 select,epoll等等
(2)IO多路复用模型的基本原理就是首先发起select/epoll系统调用,单个线程不断的轮询select/epoll系统调用所负责的成百上千的socket连接,当某个或者某些socket网络连接有数据包到达了,就返回这些可以读写的连接,再发起read/write系统调用。因此,好处也就显而易见了——通过一次select/epoll系统调用,就查询到到可以读写的一个甚至是成百上千的网络连接。
注:java中的NIO就是采用的IO复用模型,通过IO复用器Selector来轮训注册的通道,根据通道就绪的事件类型做连接数据处理。
4、AIO(异步IO)
用户线程通过系统调用,告知kernel内核启动某个IO操作,用户线程返回。kernel内核在整个IO操作(包括数据准备、数据复制)完成后,通知用户程序,用户执行后续的业务操作。