Node.js 事件循环和线程池任务完整指南
在 Node.js 的运行体系中,事件循环和线程池是保障其高效异步处理能力的核心组件。事件循环负责调度各类异步任务的执行顺序,而线程池则承担着处理 CPU 密集型及部分特定 I/O 任务的工作。接下来,我们将结合图示,详细剖析两者的工作原理,并清晰界定不同操作场景下的处理归属。
1. 事件循环的六个阶段详解
事件循环是 Node.js 实现非阻塞 I/O 和异步编程的关键机制,它按照固定顺序依次执行六个阶段,周而复始地处理任务。下面通过流程图展示事件循环的执行过程,并详细说明每个阶段的功能。
1.1 定时器阶段(Timers Phase)
处理内容:执行setTimeout和setInterval设定的回调函数。即使设置的延迟时间为 0,回调函数也不会立即执行,而是在当前调用栈清空后,此阶段按创建顺序依次执行。
示例代码:
setTimeout(() => console.log('timer1'), 0);
setTimeout(() => console.log('timer2'), 0);
// 输出顺序:timer1, timer2
所属处理:事件循环处理。
1.2 待定回调阶段(Pending Callbacks Phase)
处理内容:执行上一轮循环中因某些原因被延迟到本轮的 I/O 回调,如系统级操作(TCP 错误等)的回调。在文件 I/O 操作中,若发生错误,其错误处理回调可能在此阶段执行。
示例代码:
const fs = require('fs');
fs.readFile('file.txt', (err, data) => {if (err) handleError(err);
});
所属处理:事件循环处理。
1.3 空转阶段(Idle, Prepare Phase)
处理内容:仅供 Node.js 内部使用,主要用于准备开始轮询新的 I/O 事件,开发者通常无需直接干预。
所属处理:事件循环处理。
1.4 轮询阶段(Poll Phase)
处理内容:事件循环的核心阶段之一。先计算应阻塞和轮询 I/O 的时间,然后处理轮询队列中的事件。网络 I/O 操作(如 HTTP 请求响应、TCP 连接数据接收)、大部分文件 I/O 操作的非阻塞部分等,都在此阶段处理。
示例代码:
const net = require('net');
const server = net.createServer((socket) => {socket.on('data', (data) => {processData(data);});
});
所属处理:事件循环处理。
1.5 检查阶段(Check Phase)
处理内容:执行setImmediate设定的回调函数。setImmediate与setTimeout不同,它在当前事件循环的检查阶段执行,而setTimeout需等待定时器阶段。
示例代码:
setImmediate(() => console.log('immediate1'));
setImmediate(() => console.log('immediate2'));
所属处理:事件循环处理。
1.6 关闭回调阶段(Close Callbacks Phase)
处理内容:当连接或流关闭时,相关的关闭回调在此阶段执行,例如 TCP 连接关闭、文件流关闭等的回调处理。
示例代码:
const net = require('net');
const socket = net.connect(80, 'example.com', () => {socket.end();
});
socket.on('close', () => {console.log('连接已关闭');
});
所属处理:事件循环处理。
2. 线程池详细工作机制
Node.js 的线程池用于处理一些无法在事件循环中高效执行的任务,避免阻塞主线程。线程池的工作机制可以通过以下图示和说明来理解。
2.1 线程池大小控制
Node.js 线程池默认大小为 4,可通过process.env.UV_THREADPOOL_SIZE环境变量进行设置。线程池主要用于处理 CPU 密集型任务(如加密计算、数据压缩)以及部分特定的 I/O 操作(如同步文件读取)。
示例代码:
process.env.UV_THREADPOOL_SIZE = '8';
const crypto = require('crypto');
const tasks = Array(8).fill(null).map(() => {return new Promise((resolve) => {crypto.pbkdf2('secret','salt', 100000, 512,'sha512', resolve);});
});
Promise.all(tasks).then(() => console.log('所有加密任务完成'));
所属处理:线程池处理。
2.2 线程池任务优先级
虽然 Node.js 原生未提供严格的线程池任务优先级设置,但在实际应用中,可通过自定义逻辑实现类似功能。例如,在文件 I/O 操作中,对重要文件的读取可优先安排执行。
示例代码:
const fs = require('fs');
function readFileWithPriority(filePath, priority, callback) {// 这里可根据优先级实现任务调度逻辑fs.readFile(filePath, (err, data) => {if (err) return callback(err);console.log(`${priority === 1? '重要' : '普通'}文件已读取`);callback(null, data);});
}
readFileWithPriority('important.txt', 1, (err, data) => {if (err) throw err;
});
readFileWithPriority('normal.txt', 0, (err, data) => {if (err) throw err;
});
所属处理:线程池处理(涉及文件 I/O 的同步操作部分)。
3. 事件循环和线程池的交互
在实际的 Node.js 应用中,一个请求的处理往往需要事件循环和线程池协同工作,以下通过表格明确不同操作的处理归属,并结合代码示例展示完整请求处理流程。
操作类型 | 典型场景 | 处理归属 |
网络 I/O 操作 | HTTP 请求响应、TCP 连接数据接收 | 事件循环 |
大部分文件 I/O 操作 | 异步文件读取写入 | 事件循环 |
CPU 密集型操作 | 加密计算、数据压缩 | 线程池 |
部分特定文件 I/O 操作 | 同步文件读取 | 线程池 |
定时器回调 | setTimeout、setInterval | 事件循环 |
setImmediate回调 | 立即执行的异步任务 | 事件循环 |
关闭回调 | 连接关闭、流关闭 | 事件循环 |
3.1 完整的请求处理流程
const express = require('express');
const app = express();
const fs = require('fs').promises;
const fetch = require('node-fetch');
// 模拟从API获取数据,事件循环处理
async function fetchDataFromAPI() {const response = await fetch('https://example.com/api/data');return response.json();
}
// 模拟保存数据到数据库,事件循环处理
async function saveToDatabase(data) {// 实际中可能是与数据库交互的代码console.log('数据已保存到数据库');
}
app.get('/api/process-data', async (req, res) => {try {// 1. 网络I/O - 事件循环处理const rawData = await fetchDataFromAPI();// 2. 文件I/O - 线程池处理(同步读取config.json)const fileData = await fs.readFile('config.json');// 3. CPU密集型操作 - 线程池处理const processedData = await new Promise((resolve, reject) => {const worker = new Worker('./processor.js', {workerData: { raw: rawData, config: fileData }});worker.on('message', resolve);worker.on('error', reject);});// 4. 数据库操作 - 事件循环处理await saveToDatabase(processedData);// 5. 响应返回 - 事件循环处理res.json({ success: true, data: processedData });} catch (error) {res.status(500).json({ error: error.message });}
});
3.2 性能监控和优化
为确保应用高效运行,需对事件循环和线程池进行性能监控和优化。
// 监控事件循环延迟
const interval = 100;
let lastCheck = Date.now();
setInterval(() => {const now = Date.now();const delay = now - lastCheck - interval;console.log(`事件循环延迟: ${delay}ms`);lastCheck = now;
}, interval);
// 监控线程池使用情况
const threadPoolStats = {active: 0,queued: 0,completed: 0
};
function updateStats(type) {if (type ==='start') threadPoolStats.active++;if (type === 'end') {threadPoolStats.active--;threadPoolStats.completed++;}if (type === 'queue') threadPoolStats.queued++;
}
4. 常见问题和解决方案
4.1 事件循环阻塞
同步操作会阻塞事件循环,导致应用无法及时处理其他异步任务。
问题代码:
function blockingOperation() {const result = heavyComputation(); // 同步操作阻塞事件循环return result;
}
解决方案:
async function nonBlockingOperation() {return new Promise((resolve) => {const worker = new Worker('./heavy-computation.js');worker.on('message', resolve);});
}
4.2 内存泄漏
持续增长的数据存储(如无限制缓存)会导致内存泄漏。
问题代码:
const cache = new Map();
app.get('/api/data', (req, res) => {cache.set(Date.now(), req.body);
});
解决方案:
const LRU = require('lru-cache');
const cache = new LRU({max: 500,maxAge: 1000 * 60 * 60
});
4.3 错误处理
未捕获的异常和未处理的 Promise 拒绝会导致应用不稳定。
process.on('uncaughtException', (err) => {console.error('未捕获的异常:', err);process.exit(1);
});
process.on('unhandledRejection', (reason, promise) => {console.error('未处理的Promise拒绝:', reason);
});
5. 最佳实践总结
-
事件循环优化:避免同步操作,合理使用微任务和宏任务,监控事件循环延迟,实现优雅降级。
-
线程池管理:根据 CPU 核心数设置线程池大小,实现任务优先级,监控线程池负载,避免饱和。
-
资源管理:设置请求超时,限制内存使用,实现熔断机制,添加性能监控。
-
错误处理:实现全局错误处理,添加详细日志,实现自动恢复,监控关键指标。
通过深入理解事件循环和线程池的工作原理,合理运用上述最佳实践,能够构建出高性能、可靠的 Node.js 应用。同时,应根据实际业务场景灵活调整策略,持续关注性能监控与优化,确保应用稳定运行。
相关文章:
Node.js 事件循环和线程池任务完整指南
在 Node.js 的运行体系中,事件循环和线程池是保障其高效异步处理能力的核心组件。事件循环负责调度各类异步任务的执行顺序,而线程池则承担着处理 CPU 密集型及部分特定 I/O 任务的工作。接下来,我们将结合图示,详细剖析两者的工作…...
Java之BigDecimal
BigDecimal 是 Java 中用于高精度计算的类,特别适合需要精确十进制运算的场景,如金融计算、货币运算、概率计算等。 为什么需要 BigDecimal类 解决浮点数精度问题:float 和 double 使用二进制浮点运算,无法精确表示某些十进制小数…...
Qt5与现代OpenGL学习(四)X轴方向旋转60度
把上面两张图像放到D盘1文件夹内: shader.h #ifndef SHADER_H #define SHADER_H#include <QDebug> #include <QOpenGLShader> #include <QOpenGLShaderProgram> #include <QString>class Shader { public:Shader(const QString& verte…...
基于LVS+Keepalived+NFS的高可用负载均衡集群部署
目录 项目功能 2 项目的部署 2.1 部署环境介绍 2.2 项目的拓扑结构 2.3 项目环境调试 2.4 项目的部署 2.4.1 安装软件; 2.4.2 NFS服务器配置 2.4.3 Web节点配置 2.5 项目功能的验证 2.6 项目对应服务使用的日志 项目功能 负载均衡功能 实现原理:基于LVS(D…...
人工智能数学基础(四):线性代数
线性代数是人工智能领域的核心数学工具之一,广泛应用于数据表示、模型训练和算法优化等多个环节。本文将系统梳理线性代数的关键知识点,并结合 Python 实例,助力读者轻松掌握这一重要学科。资源绑定附上完整资源供读者参考学习! …...
基于C++的IOT网关和平台1:github项目ctGateway
初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 源码指引:github源…...
LeetCode 2962.统计最大元素出现至少 K 次的子数组:滑动窗口
【LetMeFly】2962.统计最大元素出现至少 K 次的子数组:滑动窗口 力扣题目链接:https://leetcode.cn/problems/count-subarrays-where-max-element-appears-at-least-k-times/ 给你一个整数数组 nums 和一个 正整数 k 。 请你统计有多少满足 「 nums 中…...
Nginx反向代理的负载均衡配置
Nginx 负载均衡详解 在互联网应用中,随着网站访问量的不断攀升,服务器的服务模式也需要进行相应升级。诸如分离数据库服务器、将图片作为单独服务等操作,这些都属于简单的数据负载均衡,其目的是将压力分散到不同机器上。而来自 We…...
案例速成GO+Socket,个人笔记
更多个人笔记:(仅供参考,非盈利) gitee: https://gitee.com/harryhack/it_note github: https://github.com/ZHLOVEYY/IT_note 文章目录 简单知识了解实现一个TCP 服务器与客户端(聊天室&#x…...
篮球足球体育球员综合资讯网站模板
采用帝国CMS7.5新版核心。栏目和内容模板超多变换。后台操作简单,安全可靠,性能稳定。整站浏览效果高端大气,可以帮助你快速建立一个适合自己的软件下载类型的站点! 演示地址:https://www.tmuban.com/store/620.html …...
HTTP(超文本传输协议)全面总结
HTTP(HyperText Transfer Protocol,超文本传输协议)是万维网(World Wide Web)应用中的基础协议,用于客户端与服务器之间的数据传输。随着互联网技术的发展,HTTP协议也经历了多个版本的更新&…...
OpenCV 图形API(72)图像与通道拼接函数-----根据指定的方式翻转图像(GMat)函数 flip()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 翻转一个2D矩阵,围绕垂直轴、水平轴或同时围绕两个轴。 该函数以三种不同的方式之一翻转矩阵(行和列的索引是从0开始的&a…...
【报错问题】 macOS 的安全策略(Gatekeeper)阻止了未签名的原生模块(bcrypt_lib.node)加载
这个错误是由于 macOS 的安全策略(Gatekeeper)阻止了未签名的原生模块(bcrypt_lib.node)加载 导致的。以下是具体解决方案: 1. 临时允许加载未签名模块(推荐先尝试) 在终端运行以下命令&#x…...
keep-alive具体使用方法
什么是 Keep-Alive <keep-alive> 是 Vue.js 提供的一个内置组件,用于缓存动态组件实例,从而避免重复渲染已加载过的组件。它的主要功能是在切换组件时保留状态和 DOM 结构,提升性能。 工作原理 <keep-alive> 的核心在于维护一个…...
【C++11】包装器:function与bind
前言: 上文我们学了C11中一个新的表达式:Lambda表达式。Lambda表达式可以在函数内部定义,其本质是仿函数【C11】Lambda表达式-CSDN博客 本文我们来学习C11的下一个新语法:包装器 function function的定义为: templat…...
Educational Codeforces Round 178 div2(题解ABCDE)
A. Three Decks #1.由于最后三个数会相等,提前算出来和,%3判断,再判前两个数是否大于 #include<iostream> #include<vector> #include<stdio.h> #include<map> #include<string> #include<algorithm> #…...
mermaid 序列图 解析
sequenceDiagramparticipant UI as 用户界面participant Executor as 任务执行器participant StateMgr as 状态管理器participant Repo as 数据仓库UI->>Executor: 执行任务3350c74e...Executor->>StateMgr: 更新状态为"measuring"StateMgr->>Repo…...
DTO,VO,PO,Entity
1. DTO (Data Transfer Object) 定义 DTO 是数据传输对象,用于在不同系统或层之间传输数据。 目的 简化数据传输,降低耦合,通常只包含需要传输的字段,避免暴露内部实现细节。 使用场景 Controller 和 Service 或 远程调用 之…...
Proser:重新介绍
回想Proser的定位:一款直观的【协议发送】模拟软件。 现在间断更新下来,基本成了一款通信调试助手类软件 Proser 是一款支持串口与网络的通信调试助手,其独有的协议编辑器、数据检视、标尺等功能,让指令模拟与数据分析更加易用。…...
微信小程序 首页之轮播图和搜索框 代码分享
注意!!! 只有样式,还没功能开发!!! index.wxml <!-- 搜索框 --> <view class"search"><input placeholder"请输入搜索的内容"></input><imag…...
3D可视化编辑器模版
体验地址:http://mute.turntip.cn 整个搭建平台核心模块包含如下几个部分: 3D场景渲染 组件拖拽系统 元素编辑功能 状态管理 历史记录与撤销/重做 技术栈 前端框架与库 React 18 用于构建用户界面的JavaScript库 Next.js 14 React框架,提供服…...
foc控制 - clarke变换和park变换
1. foc控制框图 下图是foc控制框图,本文主要是讲解foc控制中的larke变换和park变换clarke变换将 静止的 a b c abc abc坐标系 变换到 静止的 α β αβ αβ坐标系,本质上还是以 定子 为基准的坐标系park变换 则将 α β αβ αβ坐标系 变换到 随 转…...
DeepSeek: 探索未来的深度学习搜索引擎
深度学习驱动的下一代搜索引擎:DeepSeek 在信息爆炸的时代,搜索引擎作为连接用户与互联网世界的桥梁,其重要性不言而喻。然而,随着用户需求的日益多样化和复杂化,传统搜索引擎在理解和满足用户需求方面逐渐显现出局限…...
如何在本地部署小智服务器:从源码到全模块运行的详细步骤
小智聊天机器人本地后台服务器源码全模块部署 作者:林甲酸 -不是小女子也不是女汉子 是大女子 更新日期:2025年4月29日 🎯 前言:为什么要写这篇教程? 上周按照虾哥小智服务器的教程去部署本地后台,我用的是…...
基于论文的大模型应用:基于SmartETL的arXiv论文数据接入与预处理(四)
上一篇介绍了基于SmartETL框架实现arxiv采集处理的基本流程,通过少量的组件定制开发,配合yaml流程配置,实现了复杂的arxiv采集处理。 由于其业务流程复杂,在实际应用中还存在一些不足需要优化。 5. 基于Kafka的任务解耦设计 5.…...
GrapesJS 终极定制组件设计方案:扁平化对象属性编辑、多区域拖拽、多层嵌套与组件扩展实战
掌握 GrapesJS 复杂组件实用技巧,打造高复用、高交互的前端低代码组件体系 随着低代码可视化编辑需求日益提升,GrapesJS 作为优秀开源画布编辑器,灵活的组件机制是其核心优势。但在实际项目中,你可能会遇到: 如何编辑…...
Spring MVC 如何映射 HTTP 请求到 Controller 方法?
我们来详细分析一下如何在 Spring MVC 中将 HTTP 请求映射到 Controller 的处理方法(Handler Methods)上,以及 RequestMapping 注解的使用方法。 请求映射的核心:RequestMapping 注解 RequestMapping 是 Spring MVC 中最核心、最…...
vue.js中的一些事件修饰符【前端】
不要一直责怪过去的自己,他独自站在雾里也很迷茫。 目录 .stop:.prevent:.self:.once:.capture:.native:何时使用 .native? .stop: 作用:调用 event.stopPro…...
WEBSTORM前端 —— 第2章:CSS —— 第4节:盒子模型
目录 1.画盒子 2.Pxcook软件 3.盒子模型——组成 4.盒子模型 ——边框线 5.盒子模型——内外边距 6.盒子模型——尺寸计算 7.清除默认样式 8.盒子模型——元素溢出 9.外边距问题 ①合并现象 ②塌陷问题 10.行内元素——内外边距问题 11.盒子模型——圆角 12.盒子…...
Cursor —— AI编辑器 使用详解
Cursor - The AI Code Editor 一、Cursor 是什么? Cursor 是一款优秀的AI代码编辑器,它内置了 Deepseek-R1、GPT-4、Claude等 AI 模型。 简单说,就是:Cursor VS Code 编辑器 AI 大模型 Cursor 功能特性(代码补全、…...
故障诊断——复现github代码ClassBD-CNN(BDCNN)
刚好看到这篇文献有github代码,而且也比较新,感觉可以当作自己论文中的对比方法。 https://www.sciencedirect.com/science/article/pii/S0888327024006484 (论文地址) (看到4090,有点想劝退自己......&…...
局部和整体的关系
Prompt:为什么要研究局部和整体的关系呢?是因为很多情况下,局部就能表达出整体? 这是一个非常本质的问题,其实你已经接近数学和物理中“几何本质”的核心了。我们研究局部和整体的关系,是因为:…...
1.5 点云数据获取方式——双目立体相机
图1-5-1 双目立体相机 双目相机通过模拟人眼立体视觉,利用两个摄像头的视差信息计算物体深度,进而生成 3D 点云,具有成本低、体积小、信息丰富等优势,成为中...
Flume启动报错
报错1: 报错2: File Channel transaction capacity cannot be greater than the capacity of the channel capacit... 解决方案:删除配置...
leetcode 21. 合并两个有序链表(c++解法+相关知识点复习)
目录 题目 所需知识点复习 1.链表 1.1单链表 1.2哑结点(Dummy Node) 解答过程 1.循环双指针解法 2.递归解法 2025.4.29想到其他知识点会后续再继续补充。 题目 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表…...
链表反转_leedcodeP206
P206反转链表 原题 反转思路 将链表反转的过程分为两个区域: 🟦 未反转区(待处理) 原链表中还没有处理(还没有反转指针方向)的部分,从 current 开始一直到链表尾部。 🟩 已反转…...
Laravel+API 接口
LaravelAPI 接口 网课连接:BIlibili. 中文文档. 1.RestFul Api编码风格 一、API设计 修改hosts,C:\Windows\System32\drivers\etc\hosts,增加127.0.0.1 api.lv8.com # Laravel 框架 用这个域名来测试(推荐规范) 在…...
在 Ubuntu 上离线安装 ClickHouse
在 Ubuntu 上离线安装 ClickHouse 的步骤如下: 一.安装验证 # 检查服务状态 sudo systemctl status clickhouse-server #删除默认文件 sudo rm /etc/clickhouse-server/users.d/default-password.xml # 使用客户端连接 clickhouse-client --password...
【AI微信小程序开发】掷骰子小程序项目代码:自设骰子数量和动画(含完整前端代码)
系列文章目录 【AI微信小程序开发】AI减脂菜谱小程序项目代码:根据用户身高/体重等信息定制菜谱(含完整前端+后端代码)【AI微信小程序开发】AI菜谱推荐小程序项目代码:根据剩余食材智能生成菜谱(含完整前端+后端代码)【AI微信小程序开发】图片工具小程序项目代码:图片压…...
Linux-02-VIM和VI编辑器
第一节:什么是VI和VIM编辑器: VI是Unix和类Unix操作系统中出现的通用的文本编辑器。VIM是从VI发展出来的一个性能更强大的文本编辑器可以主动的以字体颜色辨别语法的正确性,方便程序设计,VIM和VI编辑器完全兼容。使用:vi xxx文件 或者vim xxx文件,简单来说就是用来编辑文件的一…...
同为科技 智能PDU产品选型介绍-EN10/G801FR
随着各行业对数据中心机房重视程度的不断提高, 加强机柜微环境及电源计量、监控和管理则十分必要。在新型微模块化数据中心供配电系统建设中,UPS电源、智能PDU、监控管理系统、资产管理等产品早已成为IDC机房不可或缺的部分。其中,智能PDU通过…...
NS-SWIFT微调Qwen3
目录 一、NS-SWIFT简介 二、Qwen3简介 三、微调Qwen3 1、安装NS-SWIFT环境 2、准备训练数据 3、Lora微调 4、GROP训练 5、Megatron并行训练 一、NS-SWIFT简介 SWIFT(Scalable lightWeight Infrastructure for Fine-Tuning)是魔搭ModelScope开源社…...
借 AI 热潮,深挖 [风车 AI ] 为跨境电商打造的图片翻译黑科技
家人们,这几年 AI 技术简直像坐了火箭一样飞速发展,生活里、工作中到处都能看到它的身影。对咱们跨境行业来说,语言翻译一直是个让人头疼的大问题。今天咱就借着这股 AI 热潮,好好深挖一下风车 AI 为跨境打造的那些超厉害的翻译黑…...
uni-app 中封装全局音频播放器
在开发移动应用时,音频播放功能是一个常见的需求。无论是背景音乐、音效还是语音消息,音频播放都需要一个稳定且易于管理的解决方案。在 uni-app 中,虽然原生提供了 uni.createInnerAudioContext 方法用于音频播放,但直接使用它可…...
Uniapp:设置TabBar
目录 一、setTabBarBadge:增加文本二、removeTabBarBadge:移除文本三、showTabBarRedDot:显示红点四、hideTabBarRedDot:隐藏红点一、setTabBarBadge:增加文本 为 tabBar 某一项的右上角添加文本。 uni.setTabBarBadge({index: 0,text: 1 })参数类型必填说明indexNumber…...
如何查看k8s获取系统是否清理过docker镜像
k8s集群某个节点down掉后,pod就会漂移到其他节点,但是在该节点却又执行了拉取镜像操作,明明该节点之前部署过该容器的,不知为什么又拉取了一次镜像(镜像拉取配置的优先使用本地),所以怀疑是触发…...
【Linux网络】深入解析I/O多路转接 - Select
📢博客主页:https://blog.csdn.net/2301_779549673 📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! &…...
如何解决 Xcode 签名证书和 Provisioning Profile 过期问题
在 iOS 应用开发过程中,签名证书和 Provisioning Profile 是确保应用安全性和合法性的关键组件。然而,当这些证书或配置文件过期时,开发者可能会遇到编译或归档失败的问题。本文将详细介绍如何解决 Xcode 中“iOS Distribution”证书未找到和…...
[C++]C++20协程的原理
文章目录 协程的状态机Promise 对象挂起和恢复机制协程的执行流程示例代码分析 C 协程是 C20 引入的一项重要特性,它提供了一种更简洁、高效的异步编程方式。下面从协程的状态机、Promise 对象、挂起和恢复机制等方面介绍其底层实现原理。 协程的状态机 从底层角度…...
Oracle OCP证书有效期是三年?
这一段时间,网上经常传出消息Oracle OCM认证证书有效期为三年,其实这个假消息,通过博睿谷与Oracle官方人员确认,OCP认证证书有效期是永久的。 OCP证书本身永久有效,但老版本的OCP证书代表着更多的项目经验,…...