NodeJs 中单线程和非阻塞 I/O 操作有什么区别?

2024-04-13

我一直在阅读并浏览尽可能多的 NodeJs 代码,但我对此有点困惑:

Node 单线程和非阻塞 I/O 到底意味着什么?我可以通过生成子进程来实现第一个,通过使用异步库来实现第二个。但我想弄清楚它的含义以及非阻塞 I/O 如何仍然会减慢您的应用程序的速度。


我会尽力解释。

单线程意味着 Node.js Javascript 运行时 - 在特定时间点 - 仅执行其已加载的所有代码中的一段代码。实际上,它从某个地方开始,并向下遍历所有指令(调用堆栈)直到完成。当它执行代码时,没有任何东西可以中断这个过程,并且所有 I/O 都必须等待。值得庆幸的是,大多数调用堆栈都相对较短,而且我们在 Node.js 中所做的很多事情更多的是“簿记”类型,而不是 CPU 密集型。

不过,作为单线程,任何需要很长时间的指令都会对系统的响应能力造成巨大的问题。运行时一次只能做一件事,因此一切都必须等到该指令完成。如果任何“I/O”指令(例如从磁盘读取)会阻止执行,那么系统此时将不必要地不可用。

但值得庆幸的是,我们有非阻塞 I/O。

而不是等待读取文件:

console.log(readFileSync(filePath))

你编写代码,这样你就不用等待文件被读取:

readFile(filePath)

The readFile调用几乎立即返回(可能在几纳秒内),因此运行时可以继续执行接下来的指令。但是,如果 readFile 调用在读取数据之前返回,则 readFile 调用无法返回文件内容。这就是回调的用武之地:

readFile(filePath, function(err, contents) { console.log(contents))

尽管如此,readFile呼叫几乎立即返回。运行时间可以继续。它将在它之前完成当前的工作(所有指令都在 readFile 之后)。除了存储对其的引用之外,不对传递的函数执行任何操作。

然后,在稍后的某个时间点(可能是 10 毫秒、100 毫秒或 1000 毫秒后),当读取文件完成时,将使用文件的完整内容作为第二个参数来调用回调。在此之前,运行时可以完成任意数量的其他批次的工作。

现在我将讨论您关于生成子进程和异步库的评论。你的两个说法都错了。

  • 生成子进程是让 Node.js 使用更多 CPU 核心的方法。作为单线程,单个 Node.js 没有必要使用多个内核。不过,如果您使用的是多核计算机,您可能希望使用所有这些内核。因此,启动多个 Node.js。流程。

  • Async 库不会为您提供非阻塞 I/O,Node.js 可以为您提供。 Node.js 本身没有提供一种处理来自多个回调的数据的简单方法。异步库可以帮助解决这个问题。

由于我不是 Node.js 内部的专家,欢迎指正!

相关问题:

  • 异步与非阻塞 https://stackoverflow.com/questions/2625493/asynchronous-vs-non-blocking
  • 异步、非阻塞、基于事件的架构之间有什么区别? https://stackoverflow.com/questions/7931537/whats-the-difference-between-asynchronous-non-blocking-event-base-architectu
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NodeJs 中单线程和非阻塞 I/O 操作有什么区别? 的相关文章

随机推荐