网络 I/O 要经过两个阶段:
- 等待数据就绪
- 从内核复制数据到用户进程
这两个阶段上阻塞与否,就出现了本文所讲的各种 I/O 模型的不同。
以 read() 为例。
阻塞式 I/O
Blocking I/O model在等待数据就绪和复制数据阶段均阻塞。
非阻塞 I/O
Non-blocking I/O model在等待数据就绪阶段,如果数据未就绪 read 会立刻返回 error,不阻塞;用户需要轮询以确认数据就绪;当就绪后则复制数据,该过程阻塞。
I/O 复用
I/O multiplexing model以 select() 为例。
这个概念稍有不同,它是在执行 select() 的时候,同时阻塞多个 fd 然后等到监测到某些 fd 就绪时返回。此时进程两阶段均被阻塞,但等待数据就绪阶段由 select() 阻塞,复制数据阶段由 read() 阻塞。
信号驱动 I/O
等待数据就绪阶段不阻塞,数据就绪后内核给进程发 signal,复制数据阶段阻塞。
异步 I/O
Paste_Image.png异步-回调模型。两阶段均不阻塞,数据复制完后内核给进程发 signal。
也就是说,同步 I/O 也包括非阻塞 I/O,因为非阻塞 I/O 也会在数据复制时阻塞进程。
网友评论