什么叫做I/O
I/O: 通常指输入(Input)和输出(Output)的意思,泛指操作系统数据交换和人机交互的通道。
I/O模型: 可以简单理解为 读取/写入的操作模式。
针对不同的应用场景,可以划分为:磁盘I/O模型、*网络I/O模型,内存映射I/O模型 等。
I/O 操作经常涉及到几个概念:同步/异步、阻塞/非阻塞。
- 同步/异步: 描述的是用户线程与内核的 交互方式:
- 同步 是指用户线程发起 I/O 请求后内核需要在一定的时间内给出反馈,用户线程才能继续执行;
- 异步 是指用户线程发送 I/O 请求后继续执行,不关心内核是否给出反馈,当内核 I/O 操作完成后会通知线程。
- 阻塞/非阻塞: 描述的是用户线程调用内核 I/O 的 操作方式:
- 阻塞 是指用户线程发起 I/O请求后,线程阻塞直到内核处理完I/O任务给出反馈,例如:阻塞式的
accept
函数; - 非阻塞 是指用户线程发起 I/O 请求后,线程不阻塞接着执行,例如:不阻塞式的
accept
函数。
- 阻塞 是指用户线程发起 I/O请求后,线程阻塞直到内核处理完I/O任务给出反馈,例如:阻塞式的
线程调用 I/O 操作的主要步骤如下(以 read
函数为例):
- 线程调用
read
函数:用户态切换到核心态; - 内核态把外部数据加载到内核的缓冲区;
- 内核把内核缓冲区的数据拷贝到进程缓冲区:核心态切换到用户态;
- 线程获取数据,完成自己的功能;
read
函数可以被设置为 阻塞 或 非阻塞 模式。
常见的I/O模型
常见的I/O模型分为五种,前四种都是同步I/O模型,最后一种是异步I/O模型:
- 同步阻塞 I/O 模型(Blocking I/O):即用户线程发出一个 I/O 请求,线程阻塞,直到内核处理完该 I/O 任务并返回状态指;创建的文件描述符,默认都是阻塞的。包括:Socket 的文件描述符;
- 同步非阻塞 I/O 模型(Non-Blocking IO):即用户线程发出一个 I/O 请求,内核会马上出反馈,用户线程不阻塞,例如:不阻塞的
accept
函数; - 多路转接 I/O 模型:例如,监视多个socket的状态,获取发生状态改变的socket(文件描述符),并进行处理;
- 信号驱动 I/O 模型:例如,当 I/O 调用结束时,主动给相关线程发送信号;
- 异步非阻塞 I/O 模型:当系统 I/O 操作完成后,系统自动通知对应线程,没有时间限制。