什么是 I/O

I 就是 Input 表示输入,O 就是 Output 表示输出,I/O 操作就是输入输出操作。什么样的操作属于 I/O操作呢 ? 比如数据库的读写操作就是 I/O 操作,因为数据库文件是存储在磁盘中的,而我们编写的程序是运行在内存中的,将内存中的数据写入数据库对于内存来说就是输出,查询数据库中的数据就是将磁盘中的数据读取到内存中,对于内存来说就是输入。

I/O 模型

从数据库中查询数据(将磁盘中的文件内容读取到内存中),由于磁盘的读写速度比较慢,查询内容越多花费时间越多。无论 I/O 操作需要花费多少时间,在 I/O 操作执行完成后,CPU 都是需要获取到操作结果的,那么问题就来了,CPU 在发出 I/O 操作指令后是否要等待 I/O 操作执行完成呢 ? 这就涉及到 I/O 操作模型了,I/O 操作的模型有两种。 第一种是 CPU 等待 I/O 操作执行完成获取到操作结果后再去执行其他指令,这是同步 I/O 操作 (阻塞I/O) 第二种是 CPU 不等待 I/O 操作执行完成CPU 在发出 I/O 指令后,内存和磁盘开始工作,CPU 继续执行其他指令。

当 I/O 操作完成后再通知 CPU I/O 操作的结果是什么。这是异步 I/O 操作 (非阻塞 I/O) 。

同步 I/O 在代码中的表现就是代码暂停执行等待 I/O 操作I/O 操作执行完成后再执行后续代码。 异步 I/O 在代码中的表现就是代码不暂停执行I/O 操作后面的代码可以继续执行,当 I/O 操作执行完成后通过回调函数的方式通知 CPU,说 I/O 操作已经完成了,基于 I/O 操作结果的其他操作可以执行了 (通知 CPU 调用回调函数)

同步 I/O 和 异步 I/O 区别就是是否等待 I/O 结果。

Node 采用的就是异步非阻塞 I/O 模型。

const fs = require(“fs”) fs.readFile(“./x.txt”, “utf-8”, function (error, data) { console.log(data) }) console.log(“Hello”) const fs = require(“fs”) const data = fs.readFileSync(“./y.txt”, { encoding: “utf-8” }) console.log(data)