I/O操作主要分成两部分:
- 数据准备,将数据加载到内核缓存
- 将内核缓存中的数据加载到用户缓存
- Synchronous blocking I/O
- Synchronous non-blocking I/O
- Asynchronous blocking I/O
- Asynchronous non-blocking I/O
阻塞和非阻塞的区别在数据准备阶段,无论是阻塞还是非阻塞都是应用主动找内核要数据,而
read
数据的过程是阻塞的,直到数据读取完。
同步、异步的区别在第二阶段,若由请求者主动的去获取数据,则为同步操作,需要说明的是
read
,write
操作也是阻塞的,直到数据读取完。若数据的read
都由kernel内核完成了(在内核read
数据的过程中,应用进程依旧可以执行其他的任务),这就是异步操作。
- I/O多路复用
I/O多路复用是指使用一个线程来检查多个文件描述符(Socket)的就绪状态,比如调用select和poll函数,传入多个文件描述符,如果有一个文件描述符就绪,则返回,否则阻塞直到超时。得到就绪状态后进行真正的操作可以在同一个线程里执行,也可以启动线程执行(比如使用线程池)。
一般情况下,I/O 复用机制需要事件分发器。 事件分发器的作用,将那些读写事件源分发给各读写事件的处理者。
涉及到事件分发器的两种模式称为:Reactor和Proactor。 Reactor模式是基于同步I/O的,而Proactor模式是和异步I/O相关的。