1 基本概念
在开始前先解释两组概念。
1.1 Blocking / Non-Blocking
Blocking和Non-Blocking通常指的这次操作会不会阻碍后续操作。比如在等红绿灯,或者遇上了堵车,我们通常都会说是被堵了,导致你只能在此等着,虽然你闲下来了,但是干不了后续其他事情。
1.2 Synchronous / Asynchronous
Synchronous和Asynchronous通常指的是这次操作能不能立即得到想要的结果。如果可以,那就是Synchronous,否则就是Asynchronous。比如你去打印店打印文件,你去了之后把东西给到店主,说:“打印好告诉我,我先去忙其他的了”,这就是异步。
通常情况下就可以自由组合:
- Synchronous Blocking。
- Synchronous Non-Blocking。
- Asynchronous Non-Blocking。
2 IO 模型
在I/O模型中,设想如此场景 : application
通过kernel
的read
函数读取数据,但是kernel
还未准备好数据。那么此时read
函数有两种处理方式(大致的流程):
1 | 等待数据准备好后再返回。此时: 对于 application 是Blocking 的。对于 kernel 的read 函数是Synchronous 的。 | ||
2 | 立即返回,告知application 数据还未准备好。此时:对于 application 是Non-Blocking 的;对于 kernel 的read 函数是Asynchronous 的。由于 read 函数没有返回application 期望读到的数据,那么就必须通过另外的方式把数据给到application 。那么此时,也有2种处理方式: | 2.1 | application 一直不停的调用read 函数,直到返回了期望读到的数据。此时read 函数虽然没有Blocking 到application ,但是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 。 |
2.1 Blocking I/O
对应上述表格中的1。这种方式模型简单,Blocking
时application
的进程/线程被挂起,基本不会占用CPU
资源。但是当并发大时就需要创建N个进程/线程,造成内存、线程切换开销增大。
2.2 Non-Blocking I/O
对应上述表格中的2.1。这种方式明显看起来和Blocking
没什么区别,不停的调用会造成CPU负担过重。
2.3 I/O Multiplexing (select, poll, epoll)
对应上述表格中的2.1。但是会同时通过(select, poll, epoll)在一个进程/线程中Blocking
多个连接(故而称为I/O多路复用
),当其中有一个连接的有数据可读时就返回。但是实质上还是Blocking
的,只是不会Blocking
到read
环节,而是(select, poll, epoll)环节。因为不会为每个连接创建对应的进程/线程,故而性能较好。
2.4 Signal Driven I/O (SIGIO)
对应上述表格中的2.2.1。
2.5 Asynchronous I/O (POSIX aio, Windows iocp)
对应上述表格中的2.2.2。当application
接收到回调通知时,数据已经复制给application
,故而性能最佳。
3 Reference
The C10K Problem
Select
Epoll
AIO(Asynchronous Input/Output)
IOCP(Input/Output Completion Port)
- https://en.wikipedia.org/wiki/Windows_NT_3.5
- https://en.wikipedia.org/wiki/Input/output_completion_port
- https://docs.microsoft.com/zh-cn/windows/win32/fileio/i-o-completion-ports
I/O Model Article