Node.js 工作线程与子进程:应该使用哪一个
Node.js 工作线程与子进程:应该使用哪一个
并行处理在计算密集型应用程序中起着至关重要的作用。例如,考虑一个确定给定数字是否为素数的应用程序。如果我们熟悉素数,我们就会知道必须从 1 遍历到该数的平方根才能确定它是否是素数,而这通常非常耗时且计算量极大。
因此,如果我们在 Node.js 上构建此类计算量大的应用程序,我们可能会阻塞正在运行的线程很长时间。由于 Node.js 的单线程特性,不涉及 I/O 的计算密集型操作将导致应用程序停止,直到该任务完成。
因此,在构建需要执行此类任务的软件时,我们不会使用 Node.js。但是,Node.js 引入了工作线程 和子进程的概念 来帮助在 Node.js 应用程序中进行并行处理,以便我们可以并行执行特定进程。在本文中,我们将了解这两个概念并讨论何时使用它们。
Node.js 中的工作线程是什么
Node.js 能够有效地处理 I/O 操作。然而,当它遇到任何计算量大的操作时,它会导致主事件循环冻结。
当 Node.js 发现异步操作时,它将其“离岸”到线程池。但是,当它需要运行计算量大的操作时,它会在其主线程上执行该操作,这会导致应用程序阻塞,直到操作完成。因此,为了缓解这个问题,Node.js 引入了工作线程的概念,以帮助从主事件循环中卸载 CPU 密集型操作,以便开发人员可以以非阻塞方式并行生成多个线程。
它通过启动一个隔离的 Node.js 上下文来实现此目的,该上下文包含自己的 Node.js 运行时、事件循环和事件队列,该上下文在远程 V8 环境中运行。这在与主事件循环断开连接的环境中执行,从而允许主事件循环释放。
如上所示,Node.js 创建独立的运行时作为工作线程,其中每个线程独立于其他线程执行,并通过消息通道将其进程状态传达给父线程。这允许父线程继续照常执行其功能(不会被阻塞)。通过这样做,我们可以在 Node.js 中实现多线程。
在 Node.js 中使用工作线程有什么好处
正如我们所看到的,使用工作线程对于 CPU 密集型应用程序非常有益。事实上,它有几个优点:
- 性能改进:我们可以将计算繁重的操作转移到工作线程,这可以释放主线程,从而使我们的应用程序能够响应更多请求。
- 提高并行性:如果我们有一个大型进程,希望将其分成子任务并并行执行,则可以使用工作线程来执行此操作。例如,如果我们要确定 1,999,3241,123 是否为质数,则可以使用工作线程检查范围内的除数 -(WT1 中为 1 到 100,000,WT2 中为 100,001 到 200,000,等等)。这将加快我们的算法并导致更快的响应。
什么时候应该在 Node.js 中使用工作线程
如果我们考虑一下,我们应该只使用工作线程来运行与父线程隔离的计算密集型操作。
在工作线程中运行 I/O 操作是没有意义的,因为它们已经被转移到事件循环中。因此,当我们需要在隔离环境中执行计算量大的操作时,请考虑使用工作线程。
如何在 Node.js 中构建工作线程
如果所有这些听起来对我们很有吸引力,那么让我们看看如何在 Node.js 中实现工作线程。考虑下面的代码片段:
const {Worker,isMainThread,parentPort,workerData,
} = require("worker_threads");const { generatePrimes } = require("./prime");const threads = new Set();
const number = 999999;const breakIntoParts = (number, threadCount = 1) => {const parts = [];const chunkSize = Math.ceil(number / threadCount);for (let i = 0; i < number; i += chunkSize) {const end = Math.min(i + chunkSize, number);parts.push({ start: i, end });}return parts;
};if (isMainThread) {const parts = breakIntoParts(number, 5);parts.forEach((part) => {threads.add(new Worker(__filename, {workerData: {start: part.start,end: part.end,},}));});threads.forEach((thread) => {thread.on("error", (err) => {throw err;});thread.on("exit", () => {threads.delete(thread);console.log(`Thread exiting, ${threads.size} running...`);});thread.on("message", (msg) => {console.log(msg);});});
} else {const primes = generatePrimes(workerData.start, workerData.end);parentPort.postMessage(`Primes from - ${workerData.start} to ${workerData.end}: ${primes}`);
}
上面的代码片段展示了一个可以利用工作线程的理想场景。要构建工作线程,我们需要从库中导入Worker、IsMainThread、parentPort和 workerDataworker_threads 。这些定义将用于创建工作线程。
上面的代码创建了一种算法,可以查找给定范围内的所有素数。它将主线程中的范围分成不同的部分(上面示例中的五个部分),然后使用 new Worker() 来创建一个工作线程来处理每个部分。工作线程执行 else块,该块在分配给该工作线程的范围内查找素数,并最终使用 parentPort.postMessage() 将结果发送回父(主)线程。
Node.js 中的子进程是什么
子进程与工作线程不同。虽然工作线程在同一进程中提供隔离的事件循环和 V8 运行时,但子进程是整个 Node.js 运行时的单独实例。每个子进程都有自己的内存空间,并通过消息流或管道(或文件、数据库、TCP/UDP 等)等 IPC(进程间通信)技术与主进程进行通信。
在 Node.js 中使用子进程有什么好处
在 Node.js 应用程序中使用子进程会带来很多好处:
- 改进的隔离性:每个子进程都在自己的内存空间中运行,提供与主进程的隔离。这对于可能存在资源冲突或需要分离的依赖性的任务是有利的。
- 提高可扩展性:子进程在多个进程之间分配任务,这使我们可以利用多核系统并处理更多并发请求。
- 提高鲁棒性:如果子进程由于某种原因崩溃,它不会随之崩溃我们的主进程。
- 运行外部程序:子进程允许我们将外部程序或脚本作为单独的进程运行。这对于需要与其他可执行文件交互的场景非常有用。
什么时候应该在 Node.js 中使用子进程
所以,现在我们知道子进程给图片带来的好处了。了解何时应该在 Node.js 中使用子进程非常重要。根据我的经验,当我们想在 Node.js 中执行外部程序时,我建议我们使用子进程。
比如存在一种使用场景:我们必须从 Node.js 服务中运行外部可执行文件。不可能在主线程内执行二进制文件。因此,我们必须使用一个子进程来执行二进制文件。
如何在 Node.js 中构建子进程
在 Node.js 中创建子进程的方法有多种,可以使用 spawn() 、fork()、exec() 与 execFile() 等方法。
const { spawn } = require('child_process');
const child = spawn('node', ['child.js']);child.stdout.on('data', (data) => {console.log(`Child process stdout: ${data}`);
});child.on('close', (code) => {console.log(`Child process exited with code ${code}`);
});
我们所要做的就是从child_process模块导入一个 spawn() 方法,然后通过传递 CLI 参数作为参数来调用该方法。
如何在工作线程和子进程之间进行选择
现在我们知道什么是子进程和工作线程,那么了解何时使用这些技术很重要。它们都不是适合所有情况的灵丹妙药。这两种方法都适用于特定条件。
在以下情况下使用工作线程:
- 我们正在运行 CPU 密集型任务。如果我们的任务是 CPU 密集型的,那么工作线程是一个不错的选择。
- 我们的任务需要线程之间的共享内存和高效通信。工作线程具有对共享内存和用于通信的消息系统的内置支持。
在以下情况下使用子进程:
- 我们正在运行需要隔离并独立运行的任务,特别是当它们涉及外部程序或脚本时。每个子进程都在自己的内存空间中运行。
- 我们需要使用 IPC 机制(例如标准输入/输出流、消息传递或事件)在进程之间进行通信。子进程非常适合此目的。
总结
并行处理正在成为现代系统设计的一个重要方面,特别是在构建处理非常大的数据集或计算密集型任务的应用程序时。因此,在使用 Node.js 构建此类应用程序时,考虑工作线程和子进程非常重要。
如果我们的系统没有采用正确的并行处理技术进行正确设计,我们的系统可能会因过度耗尽资源而表现不佳(因为生成这些资源也会消耗大量资源)。
因此,对于软件工程师和架构师来说,清楚地验证需求并根据本文中提供的信息选择正确的工具非常重要。
相关文章:
Node.js 工作线程与子进程:应该使用哪一个
Node.js 工作线程与子进程:应该使用哪一个 并行处理在计算密集型应用程序中起着至关重要的作用。例如,考虑一个确定给定数字是否为素数的应用程序。如果我们熟悉素数,我们就会知道必须从 1 遍历到该数的平方根才能确定它是否是素数ÿ…...
python matplotlib 三维图形添加文字且不随图形变动而变动
要在三维图形中添加文字并使其不随图形变动而变动,可以使用 annotate() 方法。这个方法可以在三维图形中添加文字,并且可以指定文字的位置、对齐方式和字体大小等属性。 下面是一个示例代码,演示如何在三维图形中添加文字: impo…...
Ubuntu设置kubelet启动脚本关闭swap分区
查看swap分区 swapon -s打开swap分区 swapon -a查看/etc/fstab下所有固化的swap分区,注释 vi /etc/fstab修改kubelet.conf文件 vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf添加 ExecStartPre/sbin/swapoff -a生效 systemctl daemon-reload sys…...
MySQL数据库存储
MySQL数据库存储 MySQL数据库简介MySQL开发环境MySQL安装图形化界面工具Navicat使用 表的操作表的概念3.2 创建表3.3 修改表 数据的操作-增删改查4.1 增加数据4.2 删除数据4.3 修改数据4.4 查询数据4.4.1 基础查询4.4.2 分组查询和聚合函数4.4.4 having语句4.4.5 排序4.5 多表联…...
verilog语法进阶,时钟原语
概述: 内容 1. 时钟缓冲 2. 输入时钟缓冲 3. ODDR2作为输出时钟缓冲 1. 输入时钟缓冲 BUFGP verilog c代码,clk作为触发器的边沿触发,会自动将clk综合成时钟信号。 module primitive1(input clk,input a,output reg y); always (posed…...
案例069:基于微信小程序的计算机实验室排课与查询系统
文末获取源码 开发语言:Java 框架:SSM JDK版本:JDK1.8 数据库:mysql 5.7 开发软件:eclipse/myeclipse/idea Maven包:Maven3.5.4 小程序框架:uniapp 小程序开发软件:HBuilder X 小程序…...
C语言:将三个数从大到小输出
#include<stdio.h> int main() {int a 0;int b 0;int c 0;printf("请输入abc的值:");scanf_s("%d%d%d", &a, &b, &c);if (b > a){int tmp a;a b;b tmp;}if (c > a){int tmp a;a c;c tmp;}if (b < c){int t…...
基于Hadoop的铁路货运大数据平台设计与应用
完整下载:基于Hadoop的铁路货运大数据平台设计与应用 基于Hadoop的铁路货运大数据平台设计与应用 Design and Application of Railway Freight Big Data Platform based on Hadoop 目录 目录 2 摘要 3 关键词 4 第一章 绪论 4 1.1 研究背景 4 1.2 研究目的与意义 5 …...
Java基础题2:类和对象
1.下面代码的运行结果是() public static void main(String[] args){String s;System.out.println("s"s);}A.代码编程成功,并输出”s” B.代码编译成功,并输出”snull” C.由于String s没有初始化,代码不能…...
冒泡排序学习
冒泡排序(Bubble Sort)是一种简单的排序算法,它通过重复地交换相邻的元素来排序。具体实现如下: 1. 从待排序的数组中的第一个元素开始,依次比较相邻的两个元素。 2. 如果前一个元素大于后一个元素,则交换…...
LeetCode(65)LRU 缓存【链表】【中等】
目录 1.题目2.答案3.提交结果截图 链接: LRU 缓存 1.题目 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类: LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 k…...
网站提示“不安全”
当你在浏览网站时,有时可能会遇到浏览器提示网站不安全的情况。这通常是由于网站缺乏SSL证书所致。那么,从SSL证书的角度出发,我们应该如何解决这个问题呢? 首先,让我们简单了解一下SSL证书。SSL证书是一种用于保护网站…...
【Linux】驱动
驱动 驱动程序过程 系统调用 用户空间 内核空间 添加驱动和调用驱动 驱动程序是如何调用设备硬件 驱动 在计算机领域,驱动(Driver)是一种软件,它充当硬件设备与操作系统之间的桥梁,允许它们进行通信和协同工作。驱动程…...
Java研学-HTML
HTML 1 介绍 HTML(Hypertext Markup Language) 超文本标记语言。静态网页,用于在浏览器上显示数据 超文本: 指页面内可以包含图片、链接,甚至音乐、程序等非文字元素。 标记语言: 使用 < > 括起来的语言 超文本标记语言的结构, 包括“头”部分&am…...
SpringBoot之响应的详细解析
2. 响应 前面我们学习过HTTL协议的交互方式:请求响应模式(有请求就有响应) 那么Controller程序呢,除了接收请求外,还可以进行响应。 2.1 ResponseBody 在我们前面所编写的controller方法中,都已经设置了…...
redis:四、双写一致性的原理和解决方案(延时双删、分布式锁、异步通知MQ/canal)、面试回答模板
双写一致性 场景导入 如果现在有个数据要更新,是先删除缓存,还是先操作数据库呢?当多个线程同时进行访问数据的操作,又是什么情况呢? 以先删除缓存,再操作数据库为例 多个线程运行的正常的流程应该如下…...
智能优化算法应用:基于动物迁徙算法3D无线传感器网络(WSN)覆盖优化 - 附代码
智能优化算法应用:基于动物迁徙算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于动物迁徙算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.动物迁徙算法4.实验参数设定5.算法结果6.…...
illuminate/database 使用 五
之前文章: illuminate/database 使用 一-CSDN博客 illuminate/database 使用 二-CSDN博客 illuminate/database 使用 三-CSDN博客 illuminate/database 使用 四-CSDN博客 一、原生查询 1.1 原理 根据之前内容调用执行的静态类为Illuminate\Database\Capsule\M…...
武汉灰京文化:益智游戏的教育与娱乐完美结合
随着游戏技术的不断发展,益智类游戏正经历着一场革命性的变革,逐渐融合了教育和娱乐的元素。创新的设计和互动方式使得许多益智游戏成为了知识传递和技能训练的有效工具,同时保持了娱乐体验的趣味性。这种教育与娱乐的完美结合不仅使益智游戏…...
arcgis api for js 中的query实现数据查询
相当于服务地址中的query查询 获取图层范围内的数据4.24 import Query from arcgis/core/rest/support/Query; import * as QueryTask from "arcgis/core/rest/query";//获取图层范围内的数据4.24 _returnFeatureFromWhere(url, where, geo) {const self thisretu…...
AcWing 1250. 格子游戏(并查集)
题目链接 活动 - AcWing本课程系统讲解常用算法与数据结构的应用方式与技巧。https://www.acwing.com/problem/content/1252/ 题解 当两个点已经是在同一个连通块中,再连一条边,就围成一个封闭的圈。一般用x * n y的形式将(x, y࿰…...
CSS对文本的简单修饰
CSS格式: 格式一:在head中的style标签范围内。 < style> 在style内的只写名字不写 : < > 选择器 { 属性的名称 : 样式; 属性的名称:样式; } < style> style中的注释用/* *…...
C++17中if和switch语句的新特性
1.从C17开始,if语句允许在条件表达式里添加一条初始化语句。当仅在if语句范围内需要变量时,使用这种形式的if语句。在if语句的条件表达式里定义的变量将在整个if语句中有效,包括else部分。 std::mutex mx; bool shared_flag true; // guard…...
极坐标下的牛拉法潮流计算57节点MATLAB程序
微❤关注“电气仔推送”获得资料(专享优惠) 潮流计算: 潮流计算是根据给定的电网结构、参数和发电机、负荷等元件的运行条件,确定电力系统各部分稳态运行状态参数的计算。通常给定的运行条件有系统中各电源和负荷点的功率、枢纽…...
软件设计师——计算机网络(三)
📑前言 本文主要是【计算机网络】——软件设计师——计算机网络的文章,如果有什么需要改进的地方还请大佬指出⛺️ 🎬作者简介:大家好,我是听风与他🥇 ☁️博客首页:CSDN主页听风与他 …...
【ArkTS】循环控制与List的使用
ArkTS如何进行循环渲染 现有数据如下 class Item{name:stringimage:Resourceprice:numberdicount:numberconstructor(name:string,image:Resource,price:number,dicount?:number) {this.name namethis.image imagethis.price pricethis.dicount dicount} }private items…...
条款3:尽量使用const
文章目录 const指针和函数声明const修饰指针const修饰函数const修饰容器const应用在函数中 const限定成员函数避免const重载的代码重复总结 const指针和函数声明 const修饰指针 char greeting[] "Hello"; char* p greeting; // non-const 指针,// non-const 数据…...
Chromadb词向量数据库总结
简介 Chroma 词向量数据库是一个用于自然语言处理(NLP)和机器学习的工具,它主要用于词嵌入(word embeddings)。词向量是将单词转换为向量表示的技术,可以捕获单词之间的语义和语法关系,使得计算…...
Gin之GORM 操作数据库(MySQL)
GORM 简单介绍 GORM 是 Golang 的一个 orm 框架。简单说,ORM 就是通过实例对象的语法,完成关系型数据库的操作的技术,是"对象-关系映射"(Object/Relational Mapping) 的缩写。使用 ORM框架可以让我们更方便…...
二十七、读写文件
二十七、读写文件 27.1 文件类QFile #include <QCoreApplication>#include<QFile> #include<QDebug>int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);QFile file("D:/main.txt");if(!file.open(QIODevice::WriteOnly | QIODe…...
南通建设企业网站/2021百度热搜年度榜
在现实生活中每个人去申请贷款,批下来的额度以及利息是不一样的,这样就有许多人觉得郁闷,为什么会每个人的差距这么大。其实,我们应该想一想自己的征信情况,负债情况,工作情况等是否好,是否符合…...
开网站做备案需要什么资料/企业培训权威机构
文章目录Rust的智能指针--RefCell<T>注意:Rust的智能指针–RefCell 现在我定义一个接口Messager,用来send消息。 pub trait Messager {fn send(&self, msg: &str); }然后一个LimitTracker类型根据指定的配额来send消息* pub struct Limi…...
坂田网站建设/全网关键词搜索工具
最近鹏哥在总结目前市面流行的开源软件,努力发现有价值的项目分享给大家。如果你看到下边的官网,是不是第一感觉是这绝对是一个商业软件的官网,鹏哥告诉你,你错了!这个就是今天鹏哥要推荐的项…...
WordPress 游戏/seo优化检测
本系列文章由 yhl_leo 出品,转载请注明出处。 文章链接: http://blog.csdn.net/yhl_leo/article/details/51377490 图像处理中常常使用的一种数据类型uchar,一般它指的就是unsigned char,可以查到它的定义为: typedef …...
免费logo设计网址/seosem是什么职位
为什么80%的码农都做不了架构师?>>> 安装 添加安装源 rpm -Uvh https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm安装 yum install mysql-community-server设置 防火墙设置 firewall-cmd --zonepublic --permanent --add-servic…...
自己做网站和推广/三只松鼠软文范例500字
大清早起来就看到F-Secure LABS团队(以前叫MWR,就是那支用13个逻辑漏洞攻破Chrome浏览器的团队,是Pwn2Own专业户)发了一篇文章“Automating Pwn2Own with Jandroid” (https://labs.f-secure.com/blog/automating-pwn2own-with-jandroid/ ),讲…...