node . js中工人线程的作用是什么

  介绍

今天就跟大家聊聊有关Node . js中工人线程的作用是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

节点。js中CPU密集型应用的历史

在工人线程之前,节点。js中有多种方式执行CPU密集型应用。其中的一些为:

<李>

使用child_process模块并在一个子进程中运行CPU密集型代码

<李>

使用集群模块,在多个进程中运行多个CPU密集型操作

<李>

使用诸如微软的纳帕。js这样的第三方模块

但是受限于性能,额外引入的复杂性,占有率低,薄弱的文档化等,这些解决方案无一被广泛采用。

为CPU密集型操作使用工人线程

尽管对于JavaScript的并发性问题来说,worker_threads是一个优雅的解决方案,但其并未给JavaScript本身带来多线程特性。相反,worker_threads通过运行应用使用多个相互隔离的JavaScript工人来实现并发,而工人和父工人之间的通信由节点提供。听懵了吗? ?♂?

在节点。js中,每一个工人将拥有其自己的V8实例及事件循环(事件循环)。但和child_process不同的是,工人不共享内存。

以上概念会在后面解释。我们首先来大致看一眼如何使用工人线程。一个原生的用例看起来是这样的:

//, worker-simple.js      const  {isMainThread,工人,还以为,parentPort, workerData},=,要求(& # 39;worker_threads& # 39;);   if  (isMainThread), {   ,const  worker =, new 工人(__filename,, {workerData: {num: 5}});   ,worker.once(& # 39;消息# 39;,,(结果),=祝辞,{   ,console.log (& # 39; square  of  5, is : & # 39;,,结果);   ,})   },{else    ,parentPort.postMessage (workerData.num  *, workerData.num)   }

在上例中,我们向每个单独的工作中传入了一个数字以计算其平方值。在计算之后,子工人将结果发送回主工人线程。尽管看上去简单,但节点。js新手可能还是会有点困惑。

工人线程是如何工作的?

JavaScript语言没有多线程特性,因此,节点。js的工人线程以一种异于许多其它高级语言传统多线程的方式行事。

在节点。js中,一个工人的职责就是去执行一段父工人提供的代码(工人脚本)。这段工人脚本将会在隔绝于其它工人的环境中运行,并能够在其自身和父工人间传递消息.worker脚本既可以是一个独立的文件,也可以是一段可被eval解析的文本格式的脚本。在我们的例子中,我们将__filename作为工人脚本,因为父工人和工人代子码都在同一个脚本文件中,由isMainThread属性决定其角色。

每个工人通过消息通道连接到其父工人。子工人可以使用parentPort.postMessage()函数向消息通道中写入信息,父工人则通过调用工人实例上的worker.postMessage()函数向消息通道中写入信息。看一下图1:

节点。js中工人线程的作用是什么

一个消息通道就是一个简单的通信渠道,其两端被称作“端口# 39;。在JavaScript/NodeJS术语中,一个消息通道的两端就被叫做端口1和端口2

节点。js的工人是如何并行的?

现在关键的问题来了,JavaScript并不直接提供并发,那么两个节点。js工人要如何并行呢?答案就是V8隔离。

一个V8隔离就是chrome V8运行时的一个单独实例,包含自有的js堆和一个微任务队列。这允许了每个节点。js工人完全隔离于其它工人地运行其JavaScript代码。其缺点在于工人无法直接访问其它工人的堆数据了。

扩展js在浏览器和节点下是如何工作的?

由此,每个工人将拥有其自己的一份独立于父工人和其它工人的libuv事件循环的拷贝。

跨越js/c++的边界

实例化一个新工人,提供和父级/同级js脚本的通信,都是由c++实现版本的工人完成的。在成文时,该实现为worker.cc (https://github.com/nodejs/node/blob/921493e228/src/node_worker.cc)。

工人的实现通过worker_threads模块被暴露为用户级的JavaScript脚本。该js实现被分割为两个脚本,我将之称为:

<李>

初始化脚本工人。js -负责初始化职工实例,并建立初次父子工人通信,以确保从父工人传递工人元数据至子工人。(https://github.com/nodejs/node/blob/921493e228/lib/internal/worker.js)

<李>

执行脚本worker_thread。js -根据用户提供的workerData数据和其它父工人提供的元数据执行用户的工人js脚本。(https://github.com/nodejs/node/blob/921493e228/lib/internal/main/worker_thread.js)

node . js中工人线程的作用是什么