如何在Node.js中创建线程


Answers:


94

每个node.js进程在设计上都是单线程的。因此,要获得多个线程,您必须具有多个进程(正如其他一些发帖人所指出的那样,您还可以链接到一些库,这些库使您能够使用Node中的线程,但是没有这些库就不存在这种功能。请参阅Shawn Vincent的回答,参考https://github.com/audreyt/node-webworker-threads

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

然后,您的父进程可以在它启动的任何进程上监视close事件,然后可以强制关闭您启动的其他进程,以实现您正在谈论的一种“全部失败”的失败策略。

另请参阅: 多核计算机上的Node.js


进程可以一次并行运行还是顺序运行?
user87267867

2
子进程独立于父进程。它们具有自己的存储空间,PID和执行时间。不确定顺序是什么意思,但是可以,它们将并行运行并由OS分别调度以执行。
布莱恩

如何将用户定义的函数称为子进程?
user87267867

我如何产生一个子进程来调用函数abc(){}
user87267867 2013年

2
呵呵,当时还不知道该库,但确实像Alex Mills所说,您可以在Node中进行一些线程化工作。话虽这么说,下一个问题应该是你。。。Node是从头开始设计的,目的是使程序员摆脱线程带来的复杂性,但在阻塞I / O方面产生类似的类型性能。我将编辑我的答案,以说明可以使用引用的库的事实。
布赖恩2015年



9

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

https://github.com/Microsoft/napajs

“ Napa.js是基于V8构建的多线程JavaScript运行时,其最初旨在在Bing中开发具有出色性能的高度迭代服务。随着它的发展,我们发现在对CPU限制的任务中补充Node.js很有用。 ,并具有在多个V8隔离中执行JavaScript并在它们之间进行通信的能力。Napa.js公开为Node.js模块,而它也可以嵌入到宿主进程中而不受Node.js的依赖。”



3

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

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

  • 微型工人允许产卵工人,但他们似乎共享同一个消息循环(但可能是我做错了– 线程具有更多文档,使我确信它确实使用了多个流程,因此我一直坚持下去,直到它起作用为止)
  • webworker线程不允许require在我需要的工作程序中添加模块

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


1
我很欣赏这个答案中的伟大思想!
MLissCetrus

3

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

2
这是您的文章:blog.logrocket.com/…吗?
serv-inc

不..不是...我确实把它及时回了。
priyeshdkr



0

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

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


2
这与线程无关。它们都在同一线程中运行。
Evan Carroll

@EvanCarroll-感谢您提醒我我不够清楚。我以关于为什么有人可能查找线程竞赛的假设作为开头,并指出这在Node的事件循环中使用了promise。来自另一种语言,很可能您想完成线程的工作,但是还不熟悉事件循环或诺言。我想指出,如果那是您的目标,则有更简单的方法可以实现这一目标。我添加了一个括号,它不使用线程。让我知道是否可以解决问题。
smileham

它似乎也可以回答OP的标准:“如果其他所有线程之间的任何方法失败,都应该被杀死”,所以我认为这很重要。
smileham

Promise.race按顺序执行所有promise,在异步操作的情况下(或在异步功能的情况下,等待)从一个切换到另一个。
Nagabhushan Baddi

0

Node.js不使用线程。据其发明家说,这是关键特征。在其发明之时,线程是缓慢的,有问题的和困难的。Node.js的创建是对有效单核替代方案进行调查的结果。大多数Node.js爱好者仍然引用旧的说法,好像在过去50年中线程没有得到改善。

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

Google for JavaScript多线程而不是Node.js多线程。您将了解有关Web Workers,Promise和其他内容的信息。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.