IO有内存IO,网络IO,磁盘IO,我们一般说的IO指的是网络IO和磁盘IO
IO网络模型是什么?

首先我们需要了解内核空间和用户空间
虚拟内存中包含 用户空间和内核空间,
用户空间包含:应用程序
内核空间包含:操作系统和驱动程序
内核会为每个IO设备维护一个缓冲区
每一个输入操作会先看缓冲区中是都存在相应的缓冲数据,没有的话再从设备中读取。
一般来说网络输入操作做包含两个阶段
一阶段 网络数据到达网卡=》缓冲区
二阶段 缓冲区=》用户空间
常见的网络模型:
unix系统下IO模型一共五种,只有一个是异步的
阻塞 :最传统的一种IO,在读写数据过程中会发生阻塞现象。 用户进程发出IO请求后,内核查看缓冲区是否有数据,若有的话拷贝至用户空间。若没有的话用户进程进入阻塞状态,并交出CPU,当数据就绪后,内核会将数据拷贝至用户进程,并将结果反馈给用户进程,用户进程解除阻塞状态。 典型就是BIO,socket
非阻塞:用户进程不断的询问内核数据是否准备就绪,如果没有内核返回error,如果准备就绪就会立马把数据拷贝之用户进程,用户进程不会放弃CPU的占用,是一种极其浪费资源的操作,很少使用。
多路复用:目前使用比较多的模型,NIO其实就是多路复用。在连接数不是很多的情况下,性能不一定比非阻塞的好,为啥这么说呢?首先我们先了解一下多路复用实现的逻辑:先构建一张有关文件描述的表,然后调用select()函数,这些文件描述中的一个或多个准备就绪后才返回,放函数返回时告诉哪个文件描述已经准备就绪,然后再进行IO操作
也就是说若没有文件准备就绪select调用进程也会阻塞,但优点在于多个进程注册IO后,只有一个select进程被阻塞。他在于能同时处理多个连接,在单个连接时反而多了一个select的调用
其实可以采用对线程+阻塞IO实现相似的效果,但是资源占用多且效率会慢,为啥呢因为select是在内核冲进行的,效率肯定比用户线程快,而且若是每个socket都对应一个进程或线程会对资源造成极大的浪费!典型就是NIO,nginx
信号驱动:可以说是半异步,用户线程发起IO请求,会给对应的socket注册一个信号函数,然后用户线程会继续执行,当内核数据准备就绪会发送一个信号给用户函数,用户函数接收到信号后,但在信号函数中调用IO,实际上呢,还是通过用户线程是完成IO操作的,依然不是真正的异步。
异步:需要操作系统的底层支持,java7中提供了AIO用户线程发起IO请求(传递的信息包含描述符,缓冲区指针,和read相同的参数及文件的偏移),内核立马返回表示接收到请求了,不会对用户线程产生任何阻塞,后面的事全部由内核独自完成,内核在数据准备就绪后,将数据直接拷贝至用户线程,然后再给用户线程发送一个信号,告知它IO操作已经完成,可以直接使用数据了。

java中常用的三种
BIO 同步阻塞IO
NIO 同步非阻塞IO
AIO 异步IO
964

被折叠的 条评论
为什么被折叠?



