目录
一、I/O 模型简介
所谓的 I/O 就是计算机内存与外部设备之间拷贝数据数据的过程。有 5 种 I/O 模型,分别是同步阻塞 I/O、同步非阻塞 I/O、多路复用I/O、信号驱动 I/O 和异步 I/O。为什么需要这么多的 I/O 模型呢?
CPU 访问内存的速度远远高于外部设备,因此 CPU 是先把外部设备的数据读取到内存里,然后进行处理。当你的程序向外部设备发起一个读指令时,数据从外部设备拷贝到内存里需要一段时间才能完成,这个时候 CPU 做什么工作呢?是让 CPU 处理其他工作,还是让 CPU 不停地去查数据?这就是 I/O 模型要解决的问题,这里来探讨下各种网络模型。
二、I/O 模型
对于一个网络 I/O 的通信过程,比如网络数据读取,会涉及两个对象,一个是调用这个操作的用户线程,一个是操作系统的内核。一个进程的地址空间分为用户空间和内核空间,用户线程不能直接访问内核空间。
当用户发起一个网络数据读取的 I/O 操作后,会经历以下两步:
- 用户线程等待内核将数据从网卡拷贝到内核空间
- 内核将数据从内核空间拷贝到用户空间
各种 I/O 模型的区别就是他们实现这两步的方式不一致。
2.1 同步阻塞 I/O
同步阻塞 I/O (BIO) 是一种最基本的 I/O 模型,也是最常见的 IO 处理方式。在同步阻塞 I/O 模型中,当一个进程或线程发起一个 I/O 请求,该进程或线程会一直阻塞着,直到请求完成为止。
比如读取网络数据,用户线程发起 read 调用后就阻塞了,内核等待网卡数据到来,把数据从网卡拷贝到内核空间,再把用户线程唤醒。
同步阻塞 I/O 模型相对实现比较简单,易于理解和编码,在低并发场景下,可以保证数据的及时处理和响应。但在高并发场景下效率低下,因大量线程可能被阻塞,导致CPU资源浪费,难以扩展到大量并发连接的情况,创建大量线程上下文切换开销大,容易出现性能瓶颈。