标准 I/O 会存在两个阶段:(以 TCP Socket 举例)
- 数据在内核态和用户态的复制:TCP 协议栈维护着 Send Buffer(发送缓冲区)和 Recv Buffer(接收缓冲区),因此 read/write 都只是将用户态数据复制到内核态的 Socket Buffer(Send/Recv Buffer)。而 Socket Buffer 和网卡之间会通过 DMA 进行数据传输(不占用 CPU)
- 等待数据就绪:对于 read 操作来说,就绪是指 Recv Buffer 没有可读的数据;而对于 write 操作来说,就绪是指 Send Buffer 已满无法写入
BIO 称为同步阻塞 I/O,它在上述的两个阶段均会阻塞。因此 BIO 必须为每个 TCP 连接创建新线程并阻塞等待其可读或可写。服务端若想支持大量客户端连接,在 BIO 的前提下使用多线程来解决是必然的事情,下面用一个简单的例子展示: