下面介绍五种 IO 模型:阻塞式IO
非阻塞式IO
IO复用(select 和 poll)
信号驱动式IO(SIGIO)
异步IO(POSIX的aio_系列函数)
1、阻塞式IO模型
阻塞式IO模型是最常用的IO模型
默认情况下,所有套接字都是阻塞的,如下图所示:
这样的IO模型中,系统调用会从应用进程空间切换到内核空间中运行一段时间后再切换回来
只有当数据报到达并且被复制到应用进程缓冲区中或者发生错误才返回,最常见的错误返回是被信号中断
2、非阻塞式IO模型
非阻塞式IO并不让进程睡眠,而是在数据报没有准备好的时候由内核立刻返回一个错误
当一个进程循环调用非阻塞式IO等待数据报时,我们称之为“轮询”
这样做会耗费大量的CPU时间,通常只在专门提供某一功能的系统中才会用到
3、IO复用模型
IO复用的系统调用有select和poll
系统阻塞在这两个系统调用上,而不是阻塞在真正的IO系统调用上
select 调用等待数据报套接字变为可读,然后调用真正的IO系统调用去进行IO操作,将所读的数据写入应用程序缓冲区中
使用 IO 复用模型的好处在于可以同时等待多个描述符就绪,甚至可以实现复杂的等待条件
等待多个描述符的另一种实现是创建多个线程,每个线程使用一个阻塞式IO系统调用去等待一个描述符
4、信号驱动式IO模型
我们也可以设定 SIGIO 信号的信号处理方式,然后让内核在描述符就绪时发送 SIGIO 信号通知我们
这种方式就是信号驱动式IO
信号驱动式IO模型的优势在于等待数据报到达期间进程不必被阻塞,一旦数据报准备好,可以立即进行处理
5、异步IO模型
aio_开头的一些列系统调用实现了异步IO模型
这些函数的工作机制是:告知内核启动某个操作,并让内核在整个操作完全进行完成之后通知进程
信号驱动式IO是在IO操作进行之前通知进程进行相应的操作,而与此不同,异步IO模型让内核完成全部的缓冲区复制工作,直到全部工作完成才去通知进程(比如产生某个信号)