IO

IO (Input/Output,输入/输出)即数据的读取(接收)或写入(发送)操作,通常用户进程中的一个完整IO分为两阶段:用户进程空间<–>内核空间、内核空间<–>设备空间(磁盘、网络等)。

IO有内存IO、网络IO和磁盘IO三种,通常我们说的IO指的是后两者。

LINUX中进程无法直接操作I/O设备,其必须通过系统调用请求kernel来协助完成I/O动作;内核会为每个I/O设备维护一个缓冲区。

对于一个输入操作来说,进程IO系统调用后,内核会先看缓冲区中有没有相应的缓存数据,没有的话再到设备中读取,因为设备IO一般速度较慢,需要等待;内核缓冲区有数据则直接复制到进程空间。

所以,对于一个网络输入操作通常包括两个不同阶段:

等待网络数据到达网卡→读取到内核缓冲区,数据准备好;
从内核缓冲区复制数据到进程空间。

阻塞IO模型

进程发起IO系统调用后,进程被阻塞,转到内核空间处理,整个IO处理完毕后返回进程,操作成功则进程获取到数据。

非阻塞IO模型

进程发起IO系统调用后,如果内核缓冲区没有数据,需要到IO设备中读取,进程返回一个错误而不会被阻塞,进程发起IO系统调用后,如果内核缓冲区有数据,内核就会把数据返回进程。

IO复用模型

进程的多个IO可以注册到一个复用器(select)上,然后调用该select, select会监听所有注册进来的IO。
如果select没有监听的IO在内核缓冲区都没有可读数据,select调用进程会被阻塞,而当任一IO在内核缓冲区中有可数据时,select调用就会返回,而后进程再次发起读取IO,读取内核中准备好的数据。

信号驱动IO模型

当进程发起一个IO操作,会向内核注册一个信号处理函数,然后进程返回不阻塞,当内核数据就绪时会发送一个信号给进程,进程便在信号处理函数中调用IO读取数据。

异步IO模型

当进程发起一个IO操作,进程返回(不阻塞),但也不能返回果结,内核把整个IO处理完后,会通知进程结果,如果IO操作成功则进程直接获取到数据。

IO模型比较

同步IO:导致请求进程阻塞,直到I/O操作完成。
异步IO:不导致请求进程阻塞。

阻塞IO模型、非阻塞IO模型、IO复用模型、信号驱动的IO模型都为为同步IO,只有异步IO模型是异步IO。