# 五、异步 IO
# 1. 概念
应用进程把 IO 请求传给内核后,完全由内核去操作文件拷贝。内核完成相关操作后,会发信号告诉应用进程本次 IO 已经完成。
用户进程发起aio_read
操作之后,给内核传递描述符、缓冲区指针、缓冲区大小等,告诉内核当整个操作完成时,如何通知进程,然后就立刻去做其他事情了。当内核收到aio_read
后,会立刻返回,然后内核开始等待数据准备,数据准备好以后,直接把数据拷贝到用户控件,然后再通知进程本次 IO 已经完成。
在 Linux 中,通知的方式是 “信号”,分为三种情况:
- 如果这个进程正在用户态处理其他逻辑,那就强行打断,调用事先注册的信号处理函数,这个函数可以决定何时以及如何处理这个异步任务。由于信号处理函数是突然闯进来的,因此跟中断处理程序一样,有很多事情是不能做的,因此保险起见,一般是把事件 “登记” 一下放进队列,然后返回该进程原来在做的事。
- 如果这个进程正在内核态处理,例如以同步阻塞方式读写磁盘,那就把这个通知挂起来了,等到内核态的事情忙完了,快要回到用户态的时候,再触发信号通知。
- 如果这个进程现在被挂起了,例如陷入睡眠,那就把这个进程唤醒,等待 CPU 调度,触发信号通知。
# 2. 优点
- 不阻塞,数据一步到位。
- Proactor 模式(主动器)。
# 3. 缺点
- 需要操作系统的底层支持,LINUX 2.5 版本内核首现,2.6 版本产品的内核标准特性。
- 实现、开发应用难度大。
# 4. 适用场景
- 非常适合高性能高并发应用。
# 5. 方案
- Java AIO