【问题标题】:How to write Node.js code that utilizes threads?如何编写利用线程的 Node.js 代码?
【发布时间】:2016-07-06 09:50:56
【问题描述】:

这是我对节点工作原理的理解:

  • 在其中执行所有 JS 代码的单线程。
  • IO/网络调用在后台使用线程池。 (使用 libuv 这是一个 C++ 库)
  • 一旦一个 IO 操作完成,它的回调就会被推送到回调队列中,并且回调可以在下一个周期被事件循环拾取。

我想了解的是如何编写可以利用系统线程的代码?我是否用 C/C++ 编写库并为此提供 Javascript 绑定?

假设我有一些不需要 IO 但 CPU 密集型的操作/功能,所以我想在多个线程中运行它。我将如何在 Node 中做到这一点?

【问题讨论】:

    标签: node.js v8 libuv


    【解决方案1】:

    我的理解是 Node 无法做到这一点。当然,您可以用另一种语言编写程序并编写一些绑定,但 Node 本身不支持多线程。您可以改用多程序设计:启动 Node 程序的多个实例并通过 HTTP 交换消息。然后,您的操作系统将处理您的程序实例在不同 CPU 内核上的分布。

    【讨论】:

      【解决方案2】:

      Well Node 使用libuv,它实现了一个线程池。阅读here 以获得很好的解释。从文章中挑选见解

      libuv 库维护一个由 node.js 使用的线程池 在后台执行长时间运行的操作,而不会阻塞 它的主线。实际上,在底层,node.js 是 不管你喜不喜欢,都是基于线程的。

      那么或许可以研究一下 libuv 是如何做到这一点的,以及它是如何与 Node 交互的,并以此为基础制定您自己的方法?

      This answer 很好地解释了事情,展示了一些 libuv 代码,并引用了另一个 great article on libuv

      【讨论】:

        【解决方案3】:

        节点是单线程的是一个常见的误解。真相要复杂得多。虽然 Node 事件循环是单线程的,但 Node 标准库中包含的一些函数不是单线程的。

        我们运行的包含在 Node 内部的一些函数在 Event Loop 之外运行,因此在该单线程之外运行。

        所以我们在 Node 中编写的很多代码并没有完全在单线程中执行。

        您可以通过编写代码亲自测试这一点,通过实现crypto 模块中的pbkdf2 函数,真正证明并非所有Node 都是真正的单线程。

        您可以对pbkdf2 函数运行所需的时间进行基准测试,以了解线程和线程池在您的机器上的实际运行情况。因此,您可以创建各种pbkdf2 函数来表示线程。该函数将做一些昂贵的工作,您可以对其进行基准测试并使用它来检测 Node 是否是单线程的,如下所示:

        const crypto = require('crypto');
        
        const start = Date.now();
        crypto.pbkdf2('a', 'b', 100000, 512, 'sha512', () => {
          console.log('1:', Date.now() - start);
        });
        

        此功能需要相当长的时间才能运行,因此在 2015 年中期的大多数 MacBook Pro 中大约需要 1 秒。

        所以上面的回调函数正在计算一个哈希值,再次使用我上面指出的机器应该不超过 1 秒来完成,但函数的作用并不像在你的机器上执行多长时间那么重要。

        您可以添加更多函数调用来表示更多线程,还可以调整机器线程池中的线程池大小,例如process.env.UV_THREADPOOL_SIZE = 2;

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-07-17
          • 1970-01-01
          • 1970-01-01
          • 2011-08-05
          • 1970-01-01
          • 2022-11-24
          • 2018-06-03
          • 2011-07-29
          相关资源
          最近更新 更多