如何在nodejs中创建线程

Posted

技术标签:

【中文标题】如何在nodejs中创建线程【英文标题】:How to create threads in nodejs 【发布时间】:2013-09-07 21:53:45 【问题描述】:

有没有办法创建线程来一次运行多个方法?

这样,如果任何方法在所有其他线程之间失败,则应该被杀死。

【问题讨论】:

【参考方案1】:

每个 node.js 进程在设计上都是单线程的。因此,要获得多个线程,您必须拥有多个进程(正如其他一些海报所指出的那样,您还可以链接到一些库,这些库将使您能够在 Node 中使用线程,但如果没有这些库,则不存在这样的能力. 参见 Shawn Vincent 的回答,引用 https://github.com/audreyt/node-webworker-threads)

您可以从主进程启动子进程,如 node.js 文档中所示:http://nodejs.org/api/child_process.html。此页面上的示例非常好,并且非常简单。

然后,您的父进程可以监视它启动的任何进程上的关闭事件,然后可以强制关闭您启动的其他进程,以实现您正在谈论的一种失败所有停止策略的类型。

另见:Node.js on multi-core machines

【讨论】:

进程可以同时并行和顺序运行吗? 子进程独立于父进程。它们有自己的内存空间、PID 和执行时间。不确定您所说的顺序是什么意思,但是是的,它们将并行运行并由操作系统单独安排执行。 如何将用户定义的函数调用为子进程? 我怎样才能产生一个子进程来调用函数 abc() 嗯,不知道那个库,但根据 Alex Mills 的评论,你可以在 Node.js 中做一些线程工作。话虽如此,下一个问题是你应该。 . . Node 的设计初衷是为了让程序员摆脱线程带来的复杂性,但在阻塞 I/O 方面产生类似类型的性能。我将编辑我的答案,以说明可以使用引用的库。【参考方案2】:

还有至少一个库用于从 Node.js 中执行本机线程:node-webworker-threads

https://github.com/audreyt/node-webworker-threads

这基本上实现了 node.js 的Web Worker browser API。

【讨论】:

这应该是正确的。暗示节点只能产生进程而不是线程的答案是错误的。【参考方案3】:

From Node 10.5 there is now multi threading support,但它是实验性的。希望这会很快稳定下来。

查看以下资源:

PR thread。 Official Documentation 博客文章:Threads in Node 10.5.0: a practical intro

更新

从 Node v11.7.0 开始,您不必使用 --experimental-worker 标志。

发布说明:https://nodejs.org/en/blog/release/v11.7.0/

【讨论】:

【参考方案4】:

您可以使用 Napa.js 获得多线程。

https://github.com/Microsoft/napajs

“Napa.js 是一个基于 V8 构建的多线程 javascript 运行时,最初设计用于在 Bing 中开发具有不影响性能的高度迭代服务。随着它的发展,我们发现它可以在 CPU 中补充 Node.js绑定任务,具有在多个 V8 隔离中执行 JavaScript 并在它们之间进行通信的能力。Napa.js 以 Node.js 模块的形式公开,同时它也可以嵌入到宿主进程中而无需 Node.js 依赖。”

【讨论】:

【参考方案5】:

如果您使用 Rx,在 rxjs-cluster 中插入插件以将工作拆分为并行执行是相当简单的。 (免责声明:我是作者)

https://www.npmjs.com/package/rxjs-cluster

【讨论】:

【参考方案6】:

我需要 Node.js 中的真正的多线程,而对我有用的是threads 包。它生成另一个进程,拥有自己的 Node.js 消息循环,因此它们不会相互阻塞。设置很简单,文档可以帮助您快速启动和运行。您的主程序和工作人员可以通过两种方式进行通信,如果需要,可以终止工作人员“线程”。

由于多线程和 Node.js 是一个复杂且广泛讨论的话题,因此很难找到适合 my 特定需求的包。作为记录,这些对我不起作用

tiny-worker 允许生成工人,但他们似乎共享相同的消息循环(但可能是我做错了什么 - threads 有更多文档让我相信它真的使用了多个进程,所以我一直持续到成功为止) webworker-threads 不允许在我需要的工作人员中使用 require-ing 模块

对于那些问我为什么需要真正的多线程的人:对于涉及 Raspberry Pi 和中断的应用程序。一个线程处理这些中断,另一个负责存储数据(以及更多)。

【讨论】:

我很欣赏这个答案的伟大思想!【参考方案7】:

nodejs 10.5.0 版本宣布了 Node.js 中的多线程。该功能仍处于试验阶段。现在有一个新的 worker_threads 模块可用。

如果您运行 Node.js v10.5.0 或更高版本,则可以开始使用工作线程,但这是一个实验性 API。默认情况下不可用:您需要在调用 Node.js 时使用  --experimental-worker 来启用它。

这是一个启用 ES6worker_threads 的示例,在版本 12.3.1 上测试

//package.json

  "scripts": 
  "start": "node  --experimental-modules --experimental- worker index.mjs"
  ,

现在,您需要从 worker_threads 导入 Worker。 注意:您需要使用 '.mjs' 扩展名声明您的 js 文件以支持 ES6。

//index.mjs
import  Worker  from 'worker_threads';

const spawnWorker = workerData => 
    return new Promise((resolve, reject) => 
        const worker = new Worker('./workerService.mjs',  workerData );
        worker.on('message', resolve);
        worker.on('error', reject);
        worker.on('exit', code => code !== 0 && reject(new Error(`Worker stopped with 
        exit code $code`)));
    )


const spawnWorkers = () => 
    for (let t = 1; t <= 5; t++)
        spawnWorker('Hello').then(data => console.log(data));


spawnWorkers();

最后,我们创建一个workerService.mjs

//workerService.mjs
import  workerData, parentPort, threadId  from 'worker_threads';

// You can do any cpu intensive tasks here, in a synchronous way
// without blocking the "main thread"
parentPort.postMessage(`$workerData from worker $threadId`);

输出:

npm 运行开始

Hello from worker 4
Hello from worker 3
Hello from worker 1
Hello from worker 2
Hello from worker 5

【讨论】:

这是你的文章吗:blog.logrocket.com/…? 不..这不是...不过我确实及时提到了它。【参考方案8】:

现在还有https://github.com/xk/node-threads-a-gogo,虽然我不确定项目状态。

【讨论】:

【参考方案9】:

NodeJS 现在包含 threads(作为回答时的实验性功能)。

【讨论】:

【参考方案10】:

您可能正在寻找 Promise.race(本机 I/O 竞赛解决方案,而不是线程)

假设您(或其他搜索此问题的人)想要竞速线程以避免失败并避免 I/O 操作的成本,这是一种简单且原生的方式来完成它(不使用线程)。 Node 设计为单线程(查找事件循环),因此尽可能避免使用线程。如果我的假设是正确的,我建议您使用Promise.racesetTimeout(链接中的示例)。使用此策略,您将竞争一个 Promise 列表,每个 Promise 都尝试一些 I/O 操作,如果出现错误(否则超时)则拒绝该 Promise。 Promise.race 语句在第一次解决/拒绝后继续,这似乎是您想要的。希望这对某人有帮助!

【讨论】:

这与线程无关。它们都在同一个线程中运行。 @EvanCarroll - 感谢您提醒我我不够清楚。我先假设为什么有人可能会查找线程竞赛,并指出这在 Node 的事件循环中使用了 Promise。来自另一种语言,您很可能想要完成线程所做的事情,但还不熟悉事件循环或承诺。我想指出,如果这是您的目标,则有更简单的方法可以实现这一目标。我添加了一个括号,这不使用线程。让我知道这是否可以解决问题。 它似乎也回答了 OPs 标准:“如果任何方法在所有其他线程之间失败,则应该被杀死”,所以我认为它是相关的。 Promise.race 按顺序执行所有 Promise,在异步操作的情况下从一个切换到另一个(或在异步函数的情况下等待)。【参考方案11】:

Node.js 不使用线程。根据其发明者的说法,这是一个关键特征。在它发明的时候,线程是缓慢的、有问题的和困难的。 Node.js 是在对一种高效的单核替代方案进行调查后创建的。大多数 Node.js 爱好者仍然引用 ye olde 的论点,好像线程在过去 50 年中没有得到改进。

如您所知,Node.js 用于运行 JavaScript。 JavaScript 语言也经过多年发展。它现在有使用多核的方法——即线程做什么。因此,通过 JavaScript 的进步,您可以在应用程序中执行一些多核多任务。 user158 指出 Node.js 正在使用它。我对此一无所知。但是,为什么要等待 Node.js 批准 JavaScript 所提供的功能。

Google for JavaScript 多线程而不是 Node.js 多线程。您将了解 Web Worker、Promises 和其他内容。

【讨论】:

【参考方案12】:

你不能在 node.js 中本地运行多个线程,但是如果你真的需要从主线程卸载一些代码,你总是可以使用 child_process fork() 在另一个进程中运行它自己的一些代码PID 和内存。

【讨论】:

以上是关于如何在nodejs中创建线程的主要内容,如果未能解决你的问题,请参考以下文章

QT中想在子线程中创建对话窗口怎么建

如何在不同的 QT 线程中创建一个窗口?

如何使用 C++ 在 Windows 中创建守护线程?

如何计算在 Kotlin 中创建的线程数?

如何使用 CWinThread 在 MFC 中创建工作线程?

如何在 C# 的后台线程中创建 BitmapImage 缓冲区? [复制]