今天就跟大家聊聊有关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:
一个消息通道就是一个简单的通信渠道,其两端被称作“端口# 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)