搞懂BIO与AIO
彻底搞懂 AIO 与 epoll 维度一:必须厘清的两个核心概念 在深入 I/O 模型之前,我们必须先区分两组完全独立的概念,很多人在这里就已混淆: 阻塞 (Blocking) vs. 非阻塞 (Non-blocking) 关注点:应用程序在等待结果时的状态。 阻塞:发起 I/O 操作后,如果数据未就绪,当前线程会被挂起,直到操作完成。 非阻塞:发起 I/O 操作后,如果数据未就绪,函数会立刻返回一个错误码,线程不会被挂起,可以继续执行其他任务。 同步 (Synchronous) vs. 异步 (Asynchronous) 关注点:内核与应用程序之间如何交付 I/O 结果。 同步:应用程序自己负责发起 I/O 操作,并且主动去查询或等待结果。即便是非阻塞轮询,只要是“我”去问内核“好了没”,都算同步。 异步:应用程序发起 I/O 操作后便立即返回。内核会独立完成整个 I/O 过程(包括将数据从内核空间拷贝到用户空间),当一切完成后,内核会通知应用程序。 经典烧水比喻: 同步阻塞 (BIO):你守在水壶边,一直等到水烧开。 同步非阻塞 (NIO):你边看电视边烧水,每隔几分钟就跑去厨房看水开了没。 异步非阻塞 (AIO):你用一个智能水壶,告诉它水开后提醒你,然后你就可以安心做任何事,直到水壶通知你。 I/O 模型的演进之路 模型一:BIO (同步阻塞 I/O) - 一夫当关 这是最古老、最简单的模型:一个连接对应一个处理线程。 工作方式:主线程 accept 一个新连接,然后创建一个新线程来处理这个连接的 read() 和 write()。 致命缺点: 资源开销巨大:一个连接一个线程,线程的创建和上下文切换成本极高。 性能瓶颈:当成千上万个线程大部分时间都在 read() 等待数据而阻塞时,CPU 大量时间被浪费在无效的上下文切换上。它无法应对 C10K (单机一万并发) 的挑战。 模型二:I/O 多路复用 - 一人看多路 为了解决 BIO 的问题,诞生了 I/O 多路复用技术。其核心思想是:用一个(或少量)线程来监视和管理大量的网络连接(文件描述符 File Descriptor, fd)。...