IO 模型

0 I/O 模型

在I/O模型中,设想如此场景 : application通过kernelread函数读取数据,但是kernel还未准备好数据。那么此时read函数有两种处理方式(大致的流程):

1 等待数据准备好后再返回。此时:
对于applicationBlocking的。
对于kernelread函数是Synchronous的。
2 立即返回,告知application数据还未准备好。此时:
对于applicationNon-Blocking的;
对于kernelread函数是Asynchronous的。

由于read函数没有返回application期望读到的数据,那么就必须通过另外的方式把数据给到application。那么此时,也有2种处理方式:
2.1 application一直不停的调用read函数,直到返回了期望读到的数据。此时read函数虽然没有Blockingapplication,但是application也无法处理其他事情,只能不停的调用read
2.2 read函数要求application调用时提供一个callback_function,在数据准备好时通过callback_function告知application。此时application就可以继续做其他事情,直到callback_function被调用。

在处理callback_function时,也还有2种处理方式。
2.2.1 数据准备好时调用callback_function,交由application去读取。
2.2.2 数据准备好并且写入到application提供的缓冲区,调用callback_function

IO 模型

1 Blocking I/O

IO 模型

对应上述表格中的1。这种方式模型简单,Blockingapplication的进程/线程被挂起,基本不会占用CPU资源。但是当并发大时就需要创建N个进程/线程,造成内存、线程切换开销增大。

2 Non-Blocking I/O

IO 模型

对应上述表格中的2.1。这种方式明显看起来和Blocking没什么区别,不停的调用会造成CPU负担过重。

3 I/O Multiplexing (select, poll, epoll)

IO 模型

对应上述表格中的2.1。但是会同时通过(select, poll, epoll)在一个进程/线程中Blocking多个连接(故而称为I/O多路复用),当其中有一个连接的有数据可读时就返回。但是实质上还是Blocking的,只是不会Blockingread环节,而是(select, poll, epoll)环节。因为不会为每个连接创建对应的进程/线程,故而性能较好。

4 Signal Driven I/O (SIGIO)

对应上述表格中的2.2.1。

5 Asynchronous I/O (POSIX aio, Windows iocp)

IO 模型

对应上述表格中的2.2.2。当application接收到回调通知时,数据已经复制给application,故而性能最佳。