【问题标题】:Node.js - single thread, non-blocking?Node.js - 单线程,非阻塞?
【发布时间】:2015-07-06 20:02:26
【问题描述】:

我正在学习 Node.js,我读到 Node.js 是单线程和非阻塞的。

我在 JavaScript 方面有很好的背景,我确实了解回调,但我并不真正了解 Node.js 如何成为单线程并在后台运行代码。这不矛盾吗?

因为如果 Node.js 是单线程的,它仍然只能同时执行一项任务。因此,如果它在后台运行某些东西,它必须停止当前任务以在后台处理某些东西,对吧?

实际效果如何?

【问题讨论】:

标签: javascript node.js nonblocking


【解决方案1】:

事实上,Node.js 并不完全是单线程的。 Node.js 使用一个“主线程”,即执行脚本的线程。这个主线程绝不能被阻塞。因此,长时间运行的操作在单独的线程中执行。例如,Node.js 使用 libuv 库,该库维护一个用于执行 I/O 的线程池。

【讨论】:

    【解决方案2】:

    虽然 JavaScript 引擎是单线程的,但有多个线程“在后台”处理所有非阻塞 I/O 工作。

    具体来说,libuv 有一个工作线程池,等待操作系统事件、I/O 信号、正在运行的 C++ 代码等。这个池的大小由UV_THREADPOOL_SIZE 环境变量决定。

    没有 JavaScript 代码会“在后台”运行。 JavaScript 函数(即回调)计划稍后在主事件循环上运行,由其他 JS 函数或直接由 libuv 工作者运行。如果循环被阻塞,那么所有安排的事情都必须等待它。

    【讨论】:

      【解决方案3】:

      Lucas 解释得很好,但我想补充一下,如果您想利用您的处理器,可以通过一些集群库添加“节点”。

      做集群的教程:http://blog.carbonfive.com/2014/02/28/taking-advantage-of-multi-processor-environments-in-node-js/

      一些托管商会为您提供“可扩展性”选项,例如 Heroku

      无论如何,当您将 MongoDB 与 NodeJS 一起使用时(例如通过 Mongoose),它会创建多个连接。

      注意:单线程的优点是可以处理数百万用户。使用传统的多线程服务器 (apache),您需要为每个用户创建一个线程,然后您需要非常大的服务器来处理数千人。

      【讨论】:

        【解决方案4】:

        就 NodeJS 而言,“在后台”真正意味着将事情放在待办事项列表中以备后用。每当 Node 完成它正在做的事情时,它都会从待办事项列表的顶部进行选择。这就是为什么做任何实际上被阻止的事情都会破坏你的一天。 “在后台”发生的所有事情(实际上只是在待办事项列表上等待)都会停止,直到阻塞任务完成。

        【讨论】:

        • 正如 Alexis 所说,NodeJS 实际上可以通过库或Cluster Class 来利用多个线程。但重要的是要了解,这可以让您启动给定 Node 进程的多个副本。它们中的每一个仍然会像一个单线程程序一样运行。
        • 好的,这澄清了一些事情,所以如果我要调用一个具有回调到第二个阻塞函数的阻塞函数。那会和程序上的一样吗? (并且要避免?)
        • 这不是“在后台”的意思。看我的回答。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-12
        相关资源
        最近更新 更多