io模型对比
io模型 | 读写操作和阻塞阶段 |
---|---|
阻塞io | 程序阻塞于读写函数 |
非阻塞io | 读写操作总是立即返回,用户程序执行读写操作,没有数据等待就绪阶段,阻塞在读写阶段 |
io复用 | 程序阻塞于io复用系统调用,但同时可以监听多个io事件,对io本身读写操作是非阻塞的 |
SIGIO信号 | 信号触发读写就绪事件,用户程序执行读写操作。程序没有阻塞阶段。 |
异步io | 内核执行读写操作并处罚读写完成时间。程序没有阻塞阶段。 |
阻塞io
阻塞io的调用可能会因为无法立即完成而被操作系统挂起,直到等待的事情发生为止。如网络编程的connect,发起连接时,客户端发送同步报文,直到等到接收到服务器确认报文。若服务器确认报文没有立即到达客户端,connect调用将会被挂起。
非阻塞io
非阻塞io的调用总是立即返回,不管事件是否已经发生。如果事件没有立即发生,会返回-1,通过error区别出错情况。对于accept,recv而言,EAGAIN,EWOULDBLOCK,属于正常情况
在事件已经发生的情况下操作非阻塞io,才能提高程序的效率。因此非阻塞io和其他io通知机制一起使用,io复用和SIGIO信号。
io复用
应用程序向内核注册多个事件,内核监管多个事件,并在事件就绪时通过io复用函数通知应用程序。io复用本身是阻塞的epoll_wait阻塞等待到有事件就绪来临。
SIGIO信号
为一个文件描述符指定宿主进程,被认定的宿主进程会捕获到SIGIO信号,当目标文件描述符事件准备就绪时,就会触发信号处理函数
异步io
阻塞,非阻塞,io复用,信号驱动都是同步io模型,这三种io模型都是在io事件发生后,由应用程序完成的。而POSIX规范的异步io模型不同,对于异步io,用户可以直接对io执行读写操作,这些操作告诉内核用户读写缓冲区 的位置,以及io操作完成后的通知方式。异步io总是立即返回,正真的读写操作已经交给内核处理。
同步io向应用程序通知的是io就绪事件,异步io向应用程序通知的是io完成事件。