当前位置: 首页 > news >正文

node.js之---子线程(child_process)模块

为什么需要子线程(child_process)模块

Worker Threads 的基本概念

如何使用 Worker Threads

Worker Threads 的性能

Worker 线程的优势和限制

进阶用法:共享内存

为什么需要子线程(child_process)模块

在 Node.js 中,Worker Threads 模块worker_threads)提供了一种在 Node.js 单线程 中使用多线程的方式,从而能够更高效地处理计算密集型任务,避免阻塞主线程(事件循环)。这是 Node.js 中引入的一种并发处理机制,旨在提高性能,尤其是在需要大量计算的情况下。

Node.js 默认是单线程的,它通过事件循环来处理异步操作。虽然 Node.js 可以在后台异步执行 I/O 操作(如文件读取、数据库查询等),但它的事件循环在处理计算密集型任务时会被阻塞。这意味着长时间运行的 CPU 密集型任务(如大型数据处理或算法计算)可能会阻塞事件循环,从而影响整个应用的响应能力。

为了克服这个问题,Node.js 引入了 Worker Threads 模块,它允许你在单个进程中创建多个线程,每个线程都拥有自己的执行上下文,并可以并行地处理任务。

Worker Threads 的基本概念

  • 主线程(Main thread):主线程是 Node.js 应用的默认执行环境。所有的 I/O 操作和事件循环都在主线程中进行。
  • Worker 线程(Worker threads):每个 Worker 线程拥有自己的事件循环和内存空间。它们与主线程并行运行,能够处理独立的任务。

如何使用 Worker Threads

要使用 Worker Threads,首先需要引入 worker_threads 模块。每个 Worker 线程都可以通过 Worker 类来创建,主线程和 Worker 线程之间的通信是通过 消息传递 实现的。主线程可以向 Worker 线程发送消息,Worker 线程也可以向主线程发送结果。

Worker Threads 的核心 API
  • worker_threads.Worker: 用于创建一个新的 Worker 线程。
  • worker_threads.isMainThread: 一个布尔值,用来判断当前代码是否在主线程中执行。
  • worker_threads.parentPort: 主线程和 Worker 线程之间的通信通道。
  • worker_threads.workerData: 允许向 Worker 线程传递数据。
const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');if (isMainThread) {// 主线程代码console.log('主线程正在运行');// 创建 Worker 线程const worker = new Worker(__filename, {workerData: { start: 1, end: 5 }});// 监听 Worker 线程返回的消息worker.on('message', (result) => {console.log(`主线程收到结果:${result}`);});worker.on('error', (err) => {console.error('Worker 线程发生错误:', err);});worker.on('exit', (code) => {if (code !== 0) {console.error(`Worker 线程退出时的错误代码: ${code}`);}});
} else {// Worker 线程代码console.log('Worker 线程正在运行');const { start, end } = workerData;// 执行任务并将结果返回给主线程let result = 0;for (let i = start; i <= end; i++) {result += i;}parentPort.postMessage(result);  // 向主线程发送结果
}

Worker Threads 的性能

  • 线程池大小:默认情况下,Worker Threads 模块使用系统的线程池。每个 Worker 线程在独立的 CPU 核心上运行,理论上可以并行执行多个计算任务。
  • 内存隔离:每个 Worker 线程拥有独立的内存空间和执行上下文,不会与其他线程共享数据,因此可以避免传统多线程编程中的竞态条件问题。
  • 开销:每个 Worker 线程都需要一定的资源开销(内存、启动时间等),所以要谨慎创建过多的 Worker 线程。

Worker 线程的优势和限制

优点

  • 避免阻塞:Worker 线程可以并行处理计算密集型任务,不会阻塞主线程的事件循环。
  • 内存隔离:每个 Worker 线程有独立的内存空间,避免了共享内存带来的问题。
  • 更好的多核利用:可以利用多核 CPU 来并行处理任务,充分发挥硬件性能。

限制

  • 消息传递开销:线程间的通信是基于消息传递的,这可能会引入一定的延迟,尤其是在需要频繁交互的场景下。
  • 内存限制:每个 Worker 线程都需要占用一定的内存和资源,创建大量的 Worker 线程可能导致内存消耗过高。
  • 无法共享内存:Worker 线程之间没有共享内存空间,虽然可以通过 SharedArrayBuffer 实现共享内存,但这需要额外的管理和同步机制。

进阶用法:共享内存

虽然 Worker 线程之间没有直接的内存共享,但可以通过 SharedArrayBuffer 实现内存共享。SharedArrayBuffer 是一种允许在多个线程之间共享内存的结构,适用于需要高效交换大量数据的场景。

const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');
const { SharedArrayBuffer, Int32Array } = require('buffer');if (isMainThread) {const sharedBuffer = new SharedArrayBuffer(4 * Int32Array.BYTES_PER_ELEMENT);const sharedArray = new Int32Array(sharedBuffer);// 将共享内存传递给 Worker 线程const worker = new Worker(__filename, { workerData: sharedBuffer });worker.on('message', () => {console.log(`Main Thread: Shared memory content: ${sharedArray[0]}`);});
} else {const sharedArray = new Int32Array(workerData);// 修改共享内存sharedArray[0] = 42;parentPort.postMessage('done');
}

在这个例子中,SharedArrayBuffer 允许主线程和 Worker 线程之间共享内存。通过 Int32Array 视图访问和修改这块内存。

相关文章:

node.js之---子线程(child_process)模块

为什么需要子线程&#xff08;child_process&#xff09;模块 Worker Threads 的基本概念 如何使用 Worker Threads Worker Threads 的性能 Worker 线程的优势和限制 进阶用法&#xff1a;共享内存 为什么需要子线程&#xff08;child_process&#xff09;模块 在 Node.js…...

Json字符串解析失败

通过第三方服务&#xff0c;拿到响应体的data对象&#xff08;拿到的时候对象是有值的&#xff09; 通过JSON.parseObject方法&#xff0c;拿到的对象&#xff0c;值为null 通过查看对应的json字符串&#xff0c;发现命名不一样... JSONField SeriealizedName注解是用来解析j…...

LeetCode算法题——螺旋矩阵ll

题目描述 给你一个正整数n&#xff0c;生成一个包含1到n2所有元素&#xff0c;且元素按顺时针顺序螺旋排列的n x n正方形矩阵matrix 。 示例 输入&#xff1a;n 3 输出&#xff1a;[[1,2,3],[8,9,4],[7,6,5]]题解 思路&#xff1a; 将整个过程分解为逐圈填充的过程&#xf…...

【开源社区openEuler实践】hpcrunner

title: 探索 Hpcrunner&#xff1a;高性能计算的得力助手 date: ‘2024-12-31’ category: blog tags: Hpcrunner高性能计算任务调度资源优化 sig: HPC archives: ‘2024-12’ author:way_back summary: Hpcrunner 作为高性能计算领域的一款实用工具&#xff0c;专注于优化任务…...

linux下安装达梦数据库v8详解

目录 操作系统、数据库 1、下载达梦数据库 2、安装前准备 2.1、建立数据库用户和组 2.2、修改文件打开最大数 2.3、挂载镜像 2.4、新建安装目录 3、数据库安装 4、配置环境变量 5、初始化数据库实例 6、注册服务 7、使用数据库 8、卸载数据库 9、多实例管理 10、…...

Redis的常用命令

Redis中文字典网站 redis 命令手册https://redis.com.cn/commands.html Keys * 查看当前库所有的key exists ke 判断某个key是否存在 type key查看你的key是什么类型 Del key删除执行的key数据 unlink key非阻塞删除&#xff0c;仅仅将keys从keyspace元数据中删除&#xf…...

Docker入门常用命令总结

1.从远程仓库拉取一个纯净的镜像 docker pull docker .io/centos 2.创建并进入容器&#xff08;左外右内&#xff09; docker run --name xxx -dit 镜像id&#xff08;镜像名称:Tag&#xff09; /bin/bash 【参数必须放在镜像ID之前】 -i 让Docker分配一个伪终端&#xff0c;并…...

【Qt】容器控件、布局管理控件

目录 容器控件 QGroupBox QTabWidget 布局管理控件 QVBoxLayout 例子&#xff1a; QHBoxLayout 例子&#xff1a; QGridLayout 例子&#xff1a; 例子&#xff1a; QFormLayout 例子&#xff1a; QSpacerItem 例子&#xff1a; 容器控件 QGroupBox 表示一个带有…...

cesium小知识:常见的20多种property详解

要详细解释 Cesium 中所有的 Property 类,内容确实会非常丰富且详尽。 Property 基础 Property 是 Cesium 中用于表示随时间或条件变化的值的基础类。它允许你定义属性值如何根据时间、用户交互或其他逻辑动态改变。Property 的设计使得你可以创建复杂的动画和交互效果,而…...

图数据库 | 17、高可用分布式设计(上)

我们在前面的文章中&#xff0c;探索了多种可能的系统扩展方式&#xff0c;以及每种扩展方式的优劣。 本篇文章将通过具体的架构设计方案来对每一种方案的设计、投入产出比、各项指标与功能&#xff0c;以及孰优孰劣等进行评价。 在设计高性能、高可用图数据库的时候&#xf…...

1.运控概述

以下并不是我原创&#xff08;包括图片&#xff09;&#xff0c;都是来源于网络收集。如CSDN博主&#xff0c;朝夕教育&#xff0c;AI等。 什么是运动控制 运控是指“控制移动”之意&#xff0c;可以利用各种电机进行位置控制等操作&#xff0c;让机器听懂你的指令。 什么是…...

DuckDB:密钥管理器及其应用

密钥管理器(Secrets Manager)为所有使用密钥的后端提供了统一的用户界面。密钥信息可以被限定范围&#xff0c;因此不同的存储前缀可以有不同的密钥信息&#xff0c;例如允许在单个查询中连接跨组织的数据。密钥也可以持久化&#xff0c;这样就不需要在每次启动DuckDB时都指定它…...

单元测试4.0+思路总结

Jmockit使用笔记_增加代码覆盖率_覆盖try catch_使用new MockUp私有方法-CSDN博客 一般使用new MockUp模拟被测试代码中的私有方法(常用&#xff09; 使用new Expetations模拟被测试代码中的方法?...

epoll 水平ET跟边缘LT触发的区别是什么

epoll默认的是水平触发 意思就是当我们depoll默认的是水平触发 LT 模式&#xff08;水平触发&#xff09; 工作机制&#xff1a;在 LT 模式下&#xff0c;只要文件描述符&#xff08;例如套接字&#xff09;对应的 I/O 缓冲区中有数据可读或者可写空间&#xff08;对于写操作…...

设计模式 创建型 单例模式(Singleton Pattern)与 常见技术框架应用 解析

单例模式&#xff08;Singleton Pattern&#xff09;是一种创建型设计模式&#xff0c;旨在确保某个类在应用程序的生命周期内只有一个实例&#xff0c;并提供一个全局访问点来获取该实例。这种设计模式在需要控制资源访问、避免频繁创建和销毁对象的场景中尤为有用。 一、核心…...

Java项目实战II基于微信小程序的家庭大厨(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、核心代码 五、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。 一、前言 在快节奏的生活中&#xff0c;家庭聚餐成为了连接亲情…...

【JVM】总结篇-字节码篇

字节码篇 Java虚拟机的生命周期 JVM的组成 Java虚拟机的体系结构 什么是Java虚拟机 虚拟机&#xff1a;指以软件的方式模拟具有完整硬件系统功能、运行在一个完全隔离环境中的完整计算机系统 &#xff0c;是物理机的软件实现。常用的虚拟机有VMWare&#xff0c;Visual Box&…...

HTML——28.音频的引入

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>音频引入</title></head><body><!--audio:在网页中引入音频当属性名和属性值一样&#xff0c;可以只写属性名src属性:指定音频文件路径&#xff0c;必…...

Visual Point Cloud Forecasting enables Scalable Autonomous Driving——点云论文阅读(12)

此内容是论文总结,重点看思路!! 文章概述 这篇文章介绍了一个名为 ViDAR 的视觉点云预测框架,它通过预测历史视觉输入生成未来点云,作为自动驾驶的预训练任务。ViDAR 集成了语义、三维几何和时间动态信息,有效提升了感知、预测和规划等自动驾驶核心任务的性能。实验表明…...

《Xsens动捕与人形机器人训练》讲座将于1月9日下午2:30在线上召开

《Xsens动捕与人形机器人训练》讲座将于1月9日下午2:30在线上召开&#xff0c;本次讲座中来自Xsens的人形机器人与动捕技术专家Jeffrey Muller与Dennis Kloppenburg不仅将就Xsens动作捕捉系统与人形机器人行为训练中的实际应用进行详细讲解&#xff0c;同时还会对目前大家所关注…...

【Java学习笔记】Arrays类

Arrays 类 1. 导入包&#xff1a;import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序&#xff08;自然排序和定制排序&#xff09;Arrays.binarySearch()通过二分搜索法进行查找&#xff08;前提&#xff1a;数组是…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...