浅谈 IO 多路复用

之前面试准备过这里的八股,但觉得理解不够深,故打算再探深些 五种 IO 模型 阻塞 IO 非阻塞 IO IO 多路复用 信号驱动 IO 异步 IO 我们先来看看 DMA 存在的必要性 当数据到达设备端,比如说网卡。网卡接收到数据后,传统非 DMA 的形式,此时会直接触发中断,此时 CPU 介入,负责解析数据,并且将数据 Copy 到 CPU 寄存器中,然后再将 CPU 寄存器中的数据 Copy 到内核内存中,然后解析再送到 Socket 缓冲区中,最后唤醒被阻塞的线程。分析上述流程,CPU 作为整个计算机的大脑,让他来处理这种傻白甜的反复读写操作,过于浪费,这就是 DMA 存在的必要性。当网卡收到数据后,通知 DMA,DMA 负责直接将数据 Copy 到内核内存中,然后网卡触发中断,CPU 将数据进行网络协议栈的解析,然后 Copy 到对应 Socket 的缓冲区中,然后唤醒线程。等到线程被调度的时候,会进入内核态,发现数据已经准备好,然后 Copy 到内存中直接使用,这就是现代计算机的一次阻塞 IO 过程。 阻塞 IO 最简单,最易懂 厨子做菜,做不好服务生也等着,等到菜做好再上菜。 上面其实已经讲过一次阻塞 IO 的流程了,只不过是站在 DMA 和 CPU 的角度来看的。我们来看看阻塞 IO 的瓶颈有哪些? 线程在 Read 数据的时候,如果数据没有准备好,那就陷入阻塞。假设数据不是必要的,有其他重要的事情做,那这里就会成为瓶颈,线程被阻塞,无法做事。 在阻塞 IO 的模型,一个 Scoket 对应一个线程,如果此时有上万个网络连接,那内核线程能否支撑这样大的并发量,所以这里也会成为瓶颈。 所以,阻塞 IO 虽然实现起来傻白甜,那是内核要考虑的问题就多了。 非阻塞 IO 厨子做菜,服务生不断轮询反问厨子有没有做好。 这一点对应到 CPU 就是进程不断调用 read(),如果数据准备好了,read()出数据,如果数据没有准备好,read()出 fasle,得到 false 的进程就去继续调用 read()。 ...

August 11, 2025 · 小石堆