Electron 主进程中使用Worker来创建不同间隔的定时器实现过程
背景
目前主进程使用 timer.setInterval 来做间隔任务执行,但是总有用户反馈养号卡主不执行了,或者某个操作不执行了,为了排除主进程的运行造成 setInterval 阻塞可能,将 setInterval 单独处理,可以排除主进程对定时器的影响。
此外,现在每秒定时会造成很多判断动作的浪费(每个人开发时都要做这种判断操作),这就需要一层封装,将自己需要的间隔操作注册到定时服务里面去,在符合条件时再收到该操作,让开发者专注处理自己的逻辑。
Worker 作为定时器的优点
-
隔离性:定时任务不会阻塞主线程,主线程可以专注于其他任务。
-
可靠性:Worker 线程的定时触发更精准,不受主线程负载影响。
-
可管理性:一个统一的 setInterval 管理所有事件,便于扩展和维护。
-
模块化:定时逻辑封装在 Worker 中,主进程代码更简洁。
-
大规模支持:适合管理大量定时任务,性能开销更可控。
-
错误隔离:Worker 的错误不会影响主进程,便于调试。
-
复杂逻辑支持:Worker 提供独立环境,适合实现复杂的定时功能。
-
线程安全:通过 postMessage 通信,确保事件触发安全。
几个知识点
-
worker.js 可以用 webpack 配置中 target="node"进行打包处理
-
npm run dev 时的路径需要用到 process.cwd() 提取,这是 electron 开发环境常规操作
实现步骤
-
主进程中引入一个心跳闹钟类,负责存储注册事件以及接收来自 worker 的间隔事件
-
worker.js 负责接收来自主进程的注册事件,通过一个 setInterval 和求余事件,向主进程这边发送对应事件,主进程的心跳闹钟类会根据注册事件列表,来调度不同的事件下的回调函数,执行具体逻辑。
源代码实现
// HeartbeatClick.js
const { Worker } = require('worker_threads');
const path = require('path');const HEARTBEAT_LOG_PREFIX = '[Main - HeartbeatClock]';class HeartbeatClock {constructor() {this.worker = null;this.eventHandlers = new Map(); // Map<eventName, Array<Function>>this.workerPath = path.join(process.cwd(), 'src', 'main', 'worker/heartbeat.worker.js');}// 启动 Workerstart() {if (this.worker) {console.log(`${HEARTBEAT_LOG_PREFIX} Worker already running.`);return;}this.worker = new Worker(this.workerPath);this.worker.on('message', this.handleWorkerMessage.bind(this));this.worker.on('error', this.handleWorkerError.bind(this));this.worker.on('exit', this.handleWorkerExit.bind(this));console.log(`${HEARTBEAT_LOG_PREFIX} Worker started.`);// 重新注册已有的事件this.eventHandlers.forEach((_, eventName) => {this.worker.postMessage({ type: 'register', eventName });});}// 停止 Workerstop() {if (this.worker) {this.worker.terminate();this.worker = null;console.log(`${HEARTBEAT_LOG_PREFIX} Worker stopped.`);}}// 注册定时事件registerEvent(eventName, handler) {if (!eventName.startsWith('interval:') || !eventName.endsWith('s')) {throw new Error('事件名格式错误,应为 interval:Ns,例如 interval:1s');}if (typeof handler !== 'function') {throw new Error('handler 必须是一个函数');}// 如果事件名不存在,初始化一个空数组if (!this.eventHandlers.has(eventName)) {this.eventHandlers.set(eventName, []);}// 将回调函数添加到数组中const handlers = this.eventHandlers.get(eventName);handlers.push(handler);console.log(`${HEARTBEAT_LOG_PREFIX} Registered handler for event: ${eventName}, total handlers: ${handlers.length}`);// 如果 Worker 已启动,通知 Worker 注册事件if (this.worker) {this.worker.postMessage({ type: 'register', eventName });console.log(`${HEARTBEAT_LOG_PREFIX} Notified worker of event: ${eventName}`);}}// 注销定时事件unregisterEvent(eventName, handler) {if (!this.eventHandlers.has(eventName)) {console.log(`${HEARTBEAT_LOG_PREFIX} Event not found: ${eventName}`);return;}const handlers = this.eventHandlers.get(eventName);// 如果提供了特定的 handler,则只移除该 handlerif (handler && typeof handler === 'function') {const index = handlers.indexOf(handler);if (index !== -1) {handlers.splice(index, 1);console.log(`${HEARTBEAT_LOG_PREFIX} Unregistered specific handler for event: ${eventName}, remaining handlers: ${handlers.length}`);}} else {// 如果未提供 handler,则移除所有 handlerhandlers.length = 0;console.log(`${HEARTBEAT_LOG_PREFIX} Unregistered all handlers for event: ${eventName}`);}// 如果没有 handler 了,删除事件并通知 Workerif (handlers.length === 0) {this.eventHandlers.delete(eventName);if (this.worker) {this.worker.postMessage({ type: 'unregister', eventName });console.log(`${HEARTBEAT_LOG_PREFIX} Notified worker to unregister event: ${eventName}`);}}}// 处理 Worker 发送的消息handleWorkerMessage(message) {if (message.type === 'interval') {const eventName = message.eventName;if (this.eventHandlers.has(eventName)) {const handlers = this.eventHandlers.get(eventName);handlers.forEach((handler, index) => {try {handler();} catch (err) {console.error(`${HEARTBEAT_LOG_PREFIX} Error in handler ${index} for event ${eventName}:`, err);}});} else {console.log(`${HEARTBEAT_LOG_PREFIX} Unregistered event: ${eventName}`);}}}// 处理 Worker 错误handleWorkerError(err) {console.error(`${HEARTBEAT_LOG_PREFIX} Worker error:`, err);}// 处理 Worker 退出handleWorkerExit(code) {console.log(`${HEARTBEAT_LOG_PREFIX} Worker exited with code: ${code}`);this.worker = null;}
}export default HeartbeatClock;// main.js
import HeartbeatClock from './HeartbeatClock';app.on('ready', () => {createMainWindow();const heartbeatClock = new HeartbeatClock();heartbeatClock.start();// 示例:注册定时事件heartbeatClock.registerEvent('interval:1s', () => {console.log('每 1 秒执行的任务 ----- 1', Date.now());});heartbeatClock.registerEvent('interval:1s', () => {console.log('每 1 秒执行的任务 ----- 2', Date.now());});heartbeatClock.registerEvent('interval:1s', () => {console.log('每 1 秒执行的任务 ----- 3', Date.now());});heartbeatClock.registerEvent('interval:3s', () => {console.log('每 3 秒执行的任务', Date.now());});heartbeatClock.registerEvent('interval:5s', () => {console.log('每 5 秒执行的任务', Date.now());});heartbeatClock.registerEvent('interval:10s', () => {console.log('每 10 秒执行的任务', Date.now());});
});// heartbeat.worker.js
const { parentPort } = require('worker_threads');// 存储注册的间隔(秒数)和对应的事件名
const intervals = new Map(); // { intervalSeconds: eventName }
let tickCount = 0; // 计数器,从 0 开始,每秒递增
const tickInterval = 1000; // 1 秒// 每秒递增计数器并检查事件
const ticker = setInterval(() => {tickCount++; // 计数器递增intervals.forEach((eventName, intervalSeconds) => {if (tickCount % intervalSeconds === 0) {console.log(`[Worker] 触发事件: ${eventName}, tickCount: ${tickCount}`);parentPort.postMessage({ type: 'interval', eventName });}});// 可选:防止 tickCount 过大(虽然 JavaScript 数字类型安全,但仍可重置)if (tickCount >= Number.MAX_SAFE_INTEGER) {tickCount = 0;console.log('[Worker] 重置计数器');}
}, tickInterval);// 监听主进程的消息
parentPort.on('message', (message) => {if (message.type === 'register') {const eventName = message.eventName; // 例如 "interval:30s"const intervalSeconds = parseInt(eventName.split(':')[1]); // 解析出秒数,例如 30if (!intervals.has(intervalSeconds)) {intervals.set(intervalSeconds, eventName);console.log(`[Worker] 已注册事件: ${eventName}, interval: ${intervalSeconds}s`);}} else if (message.type === 'unregister') {const eventName = message.eventName;const intervalSeconds = parseInt(eventName.split(':')[1]);if (intervals.has(intervalSeconds)) {intervals.delete(intervalSeconds);console.log(`[Worker] 已注销事件: ${eventName}`);}}
});// 清理逻辑
parentPort.on('close', () => {clearInterval(ticker);intervals.clear();tickCount = 0;console.log('[Worker] 已清理定时器和事件');
});// 处理 Worker 错误
parentPort.on('error', (err) => {console.error('[Worker] 错误:', err);
});
相关文章:
Electron 主进程中使用Worker来创建不同间隔的定时器实现过程
背景 目前主进程使用 timer.setInterval 来做间隔任务执行,但是总有用户反馈养号卡主不执行了,或者某个操作不执行了,为了排除主进程的运行造成 setInterval 阻塞可能,将 setInterval 单独处理,可以排除主进程对定时器…...
用户安全架构设计
一、主动踢出,被动踢出 二、密码设计策略:密码复杂度,密码安全检查,密码失效设计,账号锁定设计,密码存储和传输加密 三、密码找回策略:密保问题,下行短信验证码,上行短信…...
2025年黑客扫段攻击激增:如何构建智能防御体系保障业务安全?
引言 2025年,随着全球物联网设备突破500亿台,黑客利用自动化工具发起的扫段攻击(IP段扫描漏洞利用)已成为企业业务安全的最大威胁之一。单次攻击可覆盖数万个IP,精准定位未修复漏洞,导致数据泄露、服务瘫痪…...
基于大模型预测胃穿孔预测与围手术期管理系统技术方案
目录 1. 系统架构模块2. 关键算法实现2.1 术前预测模型(Transformer多模态融合)2.2 术中实时分析(在线学习LSTM)3. 模块流程图(Mermaid)3.1 数据预处理系统3.2 术前预测系统3.3 术中实时分析系统4. 技术验证模块4.1 模型可解释性验证4.2 边缘计算部署架构1. 系统架构模块…...
Java转Go日记(三十六):简单的分布式
1.1.1. 简单的分布式server 目前分布式系统已经很流行了,一些开源框架也被广泛应用,如dubbo、Motan等。对于一个分布式服务,最基本的一项功能就是服务的注册和发现,而利用zk的EPHEMERAL节点则可以很方便的实现该功能。EPHEMERAL节…...
操作系统-进程与线程
操作系统 操作系统用来保护系统资源和提高稳定性的重要机制 文章目录 用户态和内核态为什么要区分状态? 进程管理进程,线程进程/线程切换进程的5种状态进程通信线程通讯进程调度算法 用户态和内核态 用户态 应用程序运行时所在的模式,权限受限…...
人体肢体渲染-一步几个脚印从头设计数字生命——仙盟创梦IDE
人体肢体动作数据集-太极拳 渲染代码 # 初始化Pygame pygame.init()# 设置窗口尺寸 WINDOW_WIDTH 800 WINDOW_HEIGHT 600 window pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT)) pygame.display.set_caption("动作回放")# 设置帧率 FPS 30 clock pyg…...
如何安全配置好CDN用于防止DDoS与Web攻击 ?
保护网站免受DDoS和Web攻击是至关重要的,CDN(内容分发网络)可以作为一种有效的防御工具。以下是一些安全配置CDN以防止DDoS和Web攻击的最佳实践: 1. 选择可靠的CDN提供商 安全功能: 选择拥有强大安全功能的CDN提供商…...
01-数据结构概述和时间空间复杂度
数据结构概述和时间空间复杂度 1. 什么是数据结构 数据结构(Data Structure)是计算机存储、组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合。 2. 什么是算法 算法(Algorithm)就是定义良好的计算…...
【ArcGIS技巧】根据地块、界址点图层生成界址线
"农经权二轮延包我已经写的差不多了,需要的一些生成四至、分割地块的功能也分享了替代的插件。前面刚分享完界址点的生成,今天分享界址线的生成,有需要的自取,至此,基本可以用这些功能完成出成果工作。" 1、…...
PC:使用WinSCP密钥文件连接sftp服务器
1. 打开winscp工具,点击“标签页”->“新标签页” 2. 点击“高级"->“高级” 3. 点击"验证"->“选择密钥文件” 选择ppk文件,如果没有ppk文件选择pem文件,会自动生成ppk文件 点击确定 4. 输入要连接到的sftp服务器的…...
RedHat7 如何更换yum镜像源
RedHat7如何更换yum镜像源? # 删除系统自带 yum rpm -qa|grep -e yum -e python-urlgrabber |xargs rpm -e --nodeps# 下载yum与wget的rpm软件包 curl -O http://mirrors.aliyun.com/centos/7/os/x86_64/Packages/yum-3.4.3-168.el7.centos.noarch.rpm curl -O ht…...
k8s 1.10.26 一次containerd失败引发kubectl不可用问题
k8s 1.10.26 一次containerd失败引发kubectl不可用问题 开机k8s 1.10.26时,报以下错误 [rootmaster ~]# kubectl get no E0515 08:03:00.914894 7993 memcache.go:265] couldnt get current server API group list: Get "https://192.168.80.50:6443/api?…...
Qt信号槽机制与UI设计完全指南:从基础原理到实战应用
目录 前言一、信号槽1.1 传参1.2 Qt信号与槽的对应关系1.2.1一对多关系1.2.2 多对一关系 二、Designer三、Layout 布局3.1 基础用法3.2 打破布局3.3 贴合窗口3.4 伸展器(Spacer)3.5 嵌套布局 四、ui指针五、QWidget六、QLabel 标签使用指南总结 前言 本…...
微信小程序van-dialog确认验证失败时阻止对话框的关闭
使用官方(Vant Weapp - 轻量、可靠的小程序 UI 组件库)的before-close: wxml: <van-dialog use-slot title"名称" show"{{ show }}" show-cancel-button bind:cancel"onClose" bind:confirm"getBackInfo"…...
嵌入式学习--江科大51单片机day7
我们在听课的过程中,可能对老师讲的有疑问,或者有些自己的理解,我们可以去问豆包,包括在写博客的时候我也是,不断去问豆包保证思考的正确性。(有人感觉豆包很low啊,其实这些基础性的东西豆包一般…...
spark和hadoop之间的区别和联系
Spark和Hadoop的对比 1. 架构层面 Hadoop: HDFS(分布式文件系统):Hadoop的核心组件之一,用于存储大规模数据。它将数据分散存储在多个节点上,通过冗余存储(默认三副本)来保证数据…...
antd mobile 点击 TabBar 切换页面
switchRoute 函数,navigate 点击的 path import { Button, TabBar } from "antd-mobile"; import { useEffect } from "react"; import { Outlet, useNavigate } from "react-router-dom"; import { useDispatch } from "react…...
20250515让飞凌的OK3588-C的核心板在Linux R4下适配以太网RTL8211F-CG为4线百兆时的接线图
20250515让飞凌的OK3588-C的核心板在Linux R4下适配以太网RTL8211F-CG为4线百兆时的接线图 2025/5/15 20:19 缘起:以前做的网线找不到了,那就再来一条吧。 引脚定义要从头来过?还好找到了一条。 开干! 万用表一对/点,几…...
大语言模型 07 - 从0开始训练GPT 0.25B参数量 - MiniMind 实机训练 预训练 监督微调
写在前面 GPT(Generative Pre-trained Transformer)是目前最广泛应用的大语言模型架构之一,其强大的自然语言理解与生成能力背后,是一个庞大而精细的训练流程。本文将从宏观到微观,系统讲解GPT的训练过程,…...
【学习心得】WSL2安装Ubuntu22.04
为了使用Docker desktop,所以我的win10需要安装一下wsl并且下载一个Ubuntu。默认Windows10/11是自带wsl的,你在进行下面操作的时候可以升级一下wsl --update 1、管理员身份打开cmd,输入命令查询所有可以下载的Linux版本 # 查看有哪些 Linux 发…...
人工智能、深度学习、机器学习的联系与区别
定义 人工智能(AI - Artificial Intelligence) :是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。它旨在让计算机能够像人类一样思考、学习和决策,涉及到诸如计算机视觉、自然语言处理…...
基于互联网和LabVIEW的多通道数据采集系统仿真设计
标题:基于互联网和LabVIEW的多通道数据采集系统仿真设计 内容:1.摘要 在当今科技飞速发展的背景下,多通道数据采集在众多领域有着广泛需求。本研究的目的是设计一个基于互联网和LabVIEW的多通道数据采集系统仿真方案。采用互联网技术实现数据的远程传输与共享&…...
【Android】Android 实现一个依赖注入的注解
Android 实现一个依赖注入的注解 🎯 目标功能 自定义注解 Inject创建一个 Injector 类,用来扫描并注入对象支持 Activity 或其他类中的字段注入 🧩 步骤一:定义注解 import java.lang.annotation.ElementType; import java.lan…...
【Ansible基础】Ansible 核心组件深度解析:控制节点、受管节点、Inventory与Playbook
目录 1 Ansible架构概述 2 控制节点(Control Node)详解 2.1 控制节点定义与功能 2.2 控制节点配置文件 3 受管节点(Managed Node)详解 3.1 受管节点特点 3.2 受管节点准备工作 3.3 连接方式对比 4 Invento…...
数据库--处理模型(Processing Model)(二)
执行查询的方法有很多,接下来将介绍以更高效和更有效率的方式执行分析工作负载(在OLAP系统中)的不同技术,包括以下内容: 执行并行性(Execution Parallelism)执行引擎(Execution Engines)执行操作符输出(Execution Operator Output)中间数据表示(Intermediate Data …...
机器学习 day03
文章目录 前言一、特征降维1.特征选择2.主成分分析(PCA) 二、KNN算法三、模型的保存与加载 前言 通过今天的学习,我掌握了机器学习中的特征降维的概念以及用法,KNN算法的基本原理及用法,模型的保存和加载 一、特征降维…...
鸿蒙OSUniApp 制作简洁高效的标签云组件#三方框架 #Uniapp
UniApp 制作简洁高效的标签云组件 在移动端应用中,标签云(Tag Cloud)是一种常见的UI组件,它以视觉化的方式展示关键词或分类,帮助用户快速浏览和选择感兴趣的内容。本文将详细讲解如何在UniApp框架中实现一个简洁高效的…...
【测试】用例篇
目录 1、如何编写测试用例: 1.1、设计测试用例时:正向思维逆向思维发散思维 2.2、万能公式 2、设计测试用例的方法 2.1、基于需求设计方法 1)等价类: 2)边界类 3)场景法 4)正交表法 5)…...
力扣-46.全排列
题目描述 给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 class Solution {List<List<Integer>> res new ArrayList<>();List<Integer> path new ArrayList<>();void backtracking(i…...
【氮化镓】HfO2钝化优化GaN 器件性能
2025年,南洋理工大学的Pradip Dalapati等人在《Applied Surface Science》期刊发表了题为《Role of ex-situ HfO2 passivation to improve device performance and suppress X-ray-induced degradation characteristics of in-situ Si3N4/AlN/GaN MIS-HEMTs》的文章。该研究基…...
STL?list!!!
一、引言 之前我们一起完成了STL库中的vector,本期我们将一起完成list这一容器,在本期学习中,我们会更加加深对于模板的认识,让我们更加能感受到模板的魅力! 二、list的介绍与相关接口 list是STL库中提供的一个链表容…...
2025.05.14华为机考笔试题-第一题-100分
📌 点击直达笔试专栏 👉《大厂笔试突围》 💻 春秋招笔试突围在线OJ 👉 笔试突围OJ 01. 优先级任务调度系统 问题描述 LYA公司的开发团队正在设计一个智能任务调度系统。该系统需要根据任务优先级动态调整执行顺序,以提高团队工作效率。系统需要支持以下三种操作:…...
紫外相机工作原理及可应用范围
紫外相机是一种利用紫外线(UV)波段进行成像的设备,紫外线可用于机器视觉应用中,以检测使用可见光无法检测到的特征,工业上使用最常见的紫外波长是365nm和395nm。紫外相机通常用于高分辨率视频显微镜、电晕检测、半导体…...
海外短剧H5/App开源系统搭建指南:多语言+国际支付+极速部署
在全球短视频与短剧内容消费热潮下,搭建一个支持多语言、集成国际支付且能快速部署的海外短剧平台,已成为内容创作者和运营者的核心需求。本文将结合行业前沿技术与开源方案,提供一套完整的系统搭建指南,助您高效实现全球化布局 …...
AWS EC2 微服务 金丝雀发布(Canary Release)方案
为什么需要实现金丝雀发布? 在当前项目的工程实践中, 已经有了充分的单元测试, 预发布环境测试, 但是还是会在线上环境出现非预期的情况, 导致线上事故, 因此, 为了提升服务质量, 需要线上能够有一个预验证的机制. 如何实现金丝雀发布? 使用AWS code deploy方案 AWS code…...
2025年5月华为H12-821新增题库带解析
IS-IS核心知识 四台路由器运行IS-IS且已经建立邻接关系,区域号和路由器的等级如图中标记,下列说法中正确的有? R2和R3都会产生ATT置位的Level-1的LSPR1没有R4产生的LSP,因此R1只通过缺省路由和R4通信R2和R3都会产生ATT置位的Leve1-2的LSPR2和…...
从单体架构到微服务:架构演进之路
引言:当“大货车”遇上“集装箱运输” 在软件开发领域,单体架构曾像一辆载满货物的大货车,将所有功能打包在一个应用中。但随着业务复杂度飙升,这辆“大货车”逐渐陷入泥潭:启动慢如蜗牛、故障波及全局、升级如履薄冰……...
从 Excel 到 Data.olllo:数据分析师的提效之路
背景:Excel 的能力边界 对许多数据分析师而言,Excel 是入门数据处理的第一工具。然而,随着业务数据量的增长,Excel 的一些固有限制逐渐显现: 操作容易出错,难以审计; 打开或操作百万行数据时&…...
Uniapp开发鸿蒙购物项目教程之样式选择器
大家好,今天依然为大家带来鸿蒙跨平台开发教程的分享,我们本系列的教程最终要做一个购物应用,通过这个项目为大家分享uniapp开发鸿蒙应用从配置开发环境到应用打包上架的完成过程。 昨天的文章实现了应用首页的轮播图,其中涉及到…...
AI全域智能监控系统重构商业清洁管理范式——从被动响应到主动预防的监控效能革命
一、四维立体监控网络技术架构 1. 人员行为监控 - 融合人脸识别、骨骼追踪与RFID工牌技术,身份识别准确率99.97% - 支持15米超距夜间红外监控(精度0.01lux) 2. 作业过程监控 - UWB厘米级定位技术(误差<0.3米&…...
协作赋能-1-制造业生产流程重构
制造业生产流程重构——从“信息孤岛”到“全链协同” 在制造业的数字化转型浪潮中,一个看似矛盾的现象正在蔓延:企业部署了ERP、MES、PLM等管理系统,却仍未摆脱“纸质工单满天飞、跨部门扯皮不断”的困境。以汽车制造业为例,其…...
游戏行业DDoS攻击类型及防御分析
游戏行业作为DDoS攻击的高发领域,攻击类型复杂多样,结合多个来源的信息,以下是其主要攻击类型及特征分析: 1. 传统流量型DDoS攻击 UDP洪水攻击:通过大量UDP报文淹没服务器端口,消耗带宽资源,导…...
嵌入式学习的第二十一天-数据结构-双向链表
一、双向链表 1.定义 双向链表是在单链表的每个结点中,再设置一个指向其钱去节点的指针域。 typedef struct DulNode {ElemType date;struct DulNode *pri;//直接前驱指针sturct DulNode *next;//直接后继指针 }DulNode,*DuLinkList;2.双向链表的创建 …...
Python爬虫第21节- 基础图形验证码识别实战
目录 前言 一、学习目标 二、环境准备 2.1 安装依赖 2.2 验证安装 三、获取验证码图片 3.1 常见获取方式 3.2 图片格式要求 四、基础识别流程 4.1 基础流程 4.2 常见问题及解决方案 五、 图像预处理提升识别率 5.1 灰度化 5.2 二值化 5.3 自定义阈值二值化 5.4…...
【React全栈进阶】从组件设计到性能优化实战指南
目录 🌟 前言🏗️ 技术背景与价值🩹 当前技术痛点🛠️ 解决方案概述👥 目标读者说明 🧠 一、技术原理剖析📊 核心概念图解💡 核心作用讲解🔧 关键技术模块说明⚖️ 技术选…...
基于EFISH-SCB-RK3576/SAIL-RK3576的消防机器人控制器技术方案
(国产化替代J1900的应急救援智能化解决方案) 一、硬件架构设计 极端环境防护系统 防爆耐高温设计: 采用陶瓷纤维复合装甲(耐温1200℃持续1小时),通过GB 26784-2023消防设备防爆认证IP68防护等级…...
插件双更新:LeetCode 刷题支持正式上线,JetBrains IDE 插件持续升级!
为了让更多开发者在真实开发与算法练习中体验 MoonBit 的高效表达与编译性能,MoonBit 语言现已实现对 JetBrains 开发环境与 LeetCode 答题平台的全面支持! 无论你是习惯用 IDE 编写项目的开发者,还是希望通过 LeetCode 刷题提升算法能力的程…...
编译OpenSSL时报错,Can‘t locate IPC/Cmd.pm in @INC perl环境
Unix / Linux / macOS $ ./Configure $ make $ make test1、make Can‘t locate IPC/Cmd.pm in INC [ Downloads ] - /source/index.html https://www.openssl.org/source/ yum -y install perl-IPC-Cmd 2.make test Can’t locate Test/More.pm in INC perl环境 yum -…...
新型智慧园区技术架构深度解析:数字孪生与零碳科技的融合实践
🏭在杭州亚运村零碳园区,光伏板与氢燃料大巴构成的能源网络,正通过数字孪生技术实现智能调度。这不仅是格力电器与龙源电力在新能源领域的创新实践,更是智慧园区4.0时代的标杆案例。当AI算法开始接管能源调度,当BIM建模…...