概念
-
内核空间和用户空间。
用户进程想要执行 IO 操作的话,必须通过 系统调用 来间接访问内核空间;
当应用程序发起 I/O 调用后,会经历:1. 内核等待 I/O 设备准备好数据;2. 内核将数据从内核空间拷贝到用户空间。 -
UNIX 系统下, IO 模型一共有 5 种: 同步阻塞 I/O、同步非阻塞 I/O、I/O 多路复用、信号驱动 I/O 和异步 I/O。
-
同步与异步(synchronous/asynchronous):
同步是一种可靠的有序运行机制,当我们进行同步操作时,后续的任务是等待当前调用返回,才会进行下一步;
异步则相反,其他任务不需要等待当前调用返回,通常依靠事件、回调等机制来实现任务间次序关系 -
阻塞与非阻塞:
在进行阻塞操作时,当前线程会处于阻塞状态,无法从事其他任务,只有当条件就绪才能继续,比如ServerSocket新连接建立完毕,或者数据读取、写入操作完成;
而非阻塞则是不管IO操作是否结束,直接返回,相应操作在后台继续处理
NIO 同步非阻塞IO(Non-blocking IO)
- read
从开始IO读的read系统调用开始,用户线程就进入阻塞状态。一直到kernel返回结果后,用户线程才解除block的状态,重新运行起来。
一般情况下,会为每个连接配套一条独立的线程,当在高并发的场景下,需要大量的线程。
多路复用 (IO Multiplexing)
一个进程可以监视多个文件描述符,一旦某个描述符就绪(一般是内核缓冲区可读/可写),内核kernel能够通知程序进行相应的IO系统调用。
IO多路复用模型的基本原理就是select/epoll系统调用,单个线程不断的轮询select/epoll系统调用所负责的成百上千的socket连接,当某个或者某些socket网络连接有数据到达了,就返回这些可以读写的连接。因此,好处也就显而易见了——通过一次select/epoll系统调用,就查询到到可以读写的一个甚至是成百上千的网络连接。
目标网络连接,提前注册到select/epoll的可查询socket列表中。kernel会查询所有可查询socket列表,当任何一个socket中的数据准备好了,select/epoll就会返回。
- select 它采用一个1024长度的数组存储数据, 所以它最多可以同时检查1024个文件描述符。
- poll 采用链表的方式存储,避免长度限制,同时避免不必要的检查
- epoll 采用事件通知机制,轮询没检查到事件便进行休眠,直到有事件通知它。 它在休眠的时候,cpu是闲置的。
多路复用IO的优点:
用select/epoll的优势在于,它可以同时处理成千上万个连接(connection)。与一条线程维护一个连接相比,I/O多路复用技术的最大优势是:系统不必创建线程,也不必维护这些线程,从而大大减小了系统的开销。
Java的NIO(new IO)技术,使用的就是IO多路复用模型。在linux系统上,使用的是epoll系统调用。
多路复用IO的缺点:
本质上,select/epoll系统调用,属于同步IO,也是阻塞IO。都需要在读写事件就绪后,自己负责进行读写,也就是说这个读写过程是阻塞的
AIO (Asynchronous I/O)
也叫 信号驱动 IO.
异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。
(1)当用户线程调用了read系统调用,立刻就可以开始去做其它的事,用户线程不阻塞。
(2)内核(kernel)就开始了IO的第一个阶段:准备数据。当kernel一直等到数据准备好了,它就会将数据从kernel内核缓冲区,拷贝到用户缓冲区(用户内存)。
(3)kernel会给用户线程发送一个信号(signal),或者回调用户线程注册的回调接口,告诉用户线程read操作完成了。
(4)用户线程读取用户缓冲区的数据,完成后续的业务操作。
IOCP/libuv下AIO: 部分线程通过BIO或NIO获取数据,一个线程进行计算,通过线程过线程之间的通讯获取io数据。
打比如:
背景:等核酸结果 出来后订机票
同步阻塞:采样完,你蹲在医院门口等结果通知;
同步非阻塞:采样完,你每隔1min刷新一下app记录;
同步非阻塞多路复用:你每隔1min刷新一下app记录,同时观察你全家的结果,并通知他们;
epoll:采样完毕,核酸结果出来医院会通知你,这时候你可以马上预定机票了;
理想异步非阻塞:采样完毕,核酸结果出来后,触发系统自动预定机票;
libuv下AIO:提交预定机票所需信息到登记系统(观察者队列),医院(系统内核)核酸结果出来后通知 (线程池),(线程池)根据登记系统信息帮助你预定机票。
参考 www.cnblogs.com/crazymakerc…
欢迎关注我的前端自检清单,我和你一起成长