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

ESP8266轻量协程调度器:零栈LeanTask与确定性多任务设计

1. 项目概述ESP8266Scheduler 是一个专为 ESP8266 平台设计的协作式多任务调度器Co-operative Multitasking Scheduler其核心目标是在资源受限的 Wi-Fi SoC 上实现轻量、确定、可预测的任务并发执行模型同时避免传统抢占式 RTOS 带来的内存开销与复杂性。它并非操作系统内核而是一个运行于 Arduino 框架之上的用户态调度抽象层通过协程Coroutine思想和显式控制权让渡yield机制在单线程上下文中模拟多任务行为。该库的设计哲学根植于嵌入式系统工程实践不牺牲确定性换取便利性不以不可控的栈空间增长为代价换取语法糖。它明确拒绝自动内存管理、动态任务创建、优先级抢占等高阶特性转而提供极简、透明、可审计的调度原语。所有任务对象必须静态声明于全局作用域所有调度决策均由开发者通过yield()和delay()显式触发——这种“手动挡”设计确保了每毫秒的 CPU 时间流向完全可知对时序敏感的物联网节点如传感器采样、LED PWM 同步、低功耗唤醒至关重要。在 ESP8266 这类仅有 80KB RAM其中仅约 50KB 可供用户代码使用、无硬件 MMU 的平台传统 FreeRTOS 实例通常需占用 16–24KB RAM而 ESP8266Scheduler 的 Task 类实例仅需 4KB 栈空间可配置LeanTask 更是零栈开销。这意味着在 32KB Flash/80KB RAM 的 ESP-01 模组上开发者可稳定部署 8–10 个独立功能模块如 Wi-Fi 管理、OTA 更新、传感器轮询、LED 动画、串口调试而无需牺牲关键的 heap 空间用于网络协议栈或 TLS 加密。2. 核心架构与运行机制2.1 协作式调度模型ESP8266Scheduler 采用经典的协作式Co-operative而非抢占式Preemptive调度策略。其本质是一个主循环驱动的有限状态机所有任务共享同一 CPU 上下文调度器本身不中断任何正在执行的任务而是严格依赖任务主动交出控制权。这一模型带来三大工程优势零中断延迟风险无定时器中断强制切换上下文关键中断服务程序如 GPIO 边沿触发、UART RX FIFO 溢出可无延迟响应内存布局绝对可控每个任务栈空间在编译期静态分配无堆碎片化风险ESP.getFreeHeap()返回值稳定可预测调试路径线性可追溯任务切换点即yield()或delay()调用处GDB 单步调试时不会出现“神秘跳转”。调度器启动后执行流程严格遵循以下循环1. 遍历任务队列查找下一个应运行的任务按注册顺序 interval 计时器 2. 若任务处于启用状态且到达执行周期则调用其 loop() 方法 3. 任务执行中若调用 yield() → 立即返回调度器执行下一任务 4. 任务执行中若调用 delay(ms) → 设置该任务下次执行时间戳返回调度器 5. 所有任务检查完毕后若无任务就绪则空闲等待实际为 yield() 循环此模型要求开发者严格遵守“短任务”原则单次loop()执行时间应远小于最小delay()周期建议 10ms否则将导致其他任务饥饿。例如一个需执行 500ms ADC 扫描的任务必须拆分为 50 次delay(10)调用每次处理 10 个通道。2.2 Task 与 LeanTask 双轨设计库提供两种任务基类针对不同资源约束场景进行工程权衡特性Task类LeanTask类栈空间4KB默认可通过TASK_STACK_SIZE宏修改零额外栈复用全局栈上下文保存使用setjmp/longjmp保存寄存器状态cont.h无上下文保存纯函数调用yield()行为交出控制权给调度器后续从yield()后续指令继续执行交出控制权给 ESP8266 系统如 WiFi 事件处理不返回当前任务delay()行为设置任务下次执行时间戳调度器跳过该任务直至超时设置任务下次执行时间戳但delay()内部不触发 yield需在loop()末尾显式调用适用场景需要复杂状态机、深度递归、长时间阻塞逻辑的任务简单周期性操作内存监控、LED 闪烁、对 RAM 极度敏感的固件LeanTask的零栈设计是其最大技术亮点。它不使用setjmp/longjmp意味着无cont.h依赖所有变量生存期严格遵循 C 函数作用域规则。这不仅节省 4KB RAM更消除了协程上下文切换的隐式开销约 200–300 cycles。但代价是LeanTask::loop()必须是原子性、无状态延续的函数——不能依赖局部变量跨delay()调用保持值所有状态必须存于类成员变量或全局变量中。2.3 调度器生命周期管理调度器启动过程高度精简仅需两步// 1. 注册任务可多次调用按注册顺序调度 Scheduler.start(blink_task); Scheduler.start(mem_task); // 2. 启动调度器阻塞式永不返回 Scheduler.begin();Scheduler.begin()是一个死循环其内部实现等效于void SchedulerClass::begin() { while (true) { // 遍历所有已注册任务 for (auto* task : task_queue) { if (task-isEnabled() task-isDue()) { task-loop(); // 执行任务主体 } } } }因此setup()函数中Scheduler.begin()必须是最后一行代码。任何在其后的语句包括Serial.println()均不会执行。Arduino 标准loop()函数在此模型下被完全弃用——调度器自身即为顶层循环。3. API 详解与工程实践3.1 AbstractTask 基类接口所有任务类均继承自AbstractTask其公共接口定义了任务生命周期控制的核心契约方法签名作用工程要点AbstractTask(bool _enabled true, unsigned long _interval 0)构造函数初始化任务启用状态与执行间隔_interval 0表示每次调度均执行实时任务_interval 0启用周期调度bool isEnabled()bool isEnabled()查询任务当前启用状态用于条件性启用/禁用如 OTA 期间暂停传感器任务void enable()void enable()启用任务调用后任务立即参与下一轮调度void disable()void disable()禁用任务立即从调度队列中移除isEnabled()返回falsevoid setInterval(unsigned long val)void setInterval(unsigned long val)动态修改执行间隔支持运行时调整如根据电池电量降低 LED 刷新率unsigned long getInterval()unsigned long getInterval()获取当前间隔值用于调试或状态同步关键工程实践setInterval()应在setup()中完成初始配置运行时修改需加锁若多任务访问同一任务对象。例如class PowerMonitorTask : public Task { public: void loop() { float vbat readBatteryVoltage(); if (vbat 3.3f) { // 低电量时延长采样间隔减少功耗 this-setInterval(30000); // 30s 一次 } else { this-setInterval(5000); // 正常 5s 一次 } } } power_monitor;3.2 SchedulerClass 静态接口调度器提供静态方法供全局控制所有方法均为线程安全单线程上下文方法签名作用工程要点start(AbstractTask *task)static void start(AbstractTask *task)将任务加入调度队列必须在Scheduler.begin()前调用重复调用同一任务指针无副作用begin()static void begin()启动调度循环阻塞调用永不返回应为setup()最后一行delay(unsigned long ms)static void delay(unsigned long ms)为当前正在运行的任务设置延迟仅对Task类有效LeanTask调用无效应直接在loop()中调用delay()yield()static void yield()强制当前任务让出控制权仅对Task类有效LeanTask调用将交出控制权给 ESP8266 系统如 WiFi 处理不保证返回典型误用规避❌ 在LeanTask::loop()中调用Scheduler.delay()—— 无效果且破坏设计意图❌ 在Task::loop()中调用::delay()全局 delay—— 阻塞整个调度器所有任务停滞✅ 正确做法Task中用delay()LeanTask中用delay() 末尾yield()若需让出。3.3 任务声明与内存布局规范强制工程约束所有任务对象必须声明为全局静态变量禁止动态分配或局部变量// ✅ 正确全局静态声明栈空间编译期确定 BlinkTask blink_task; MemTask mem_task; // ❌ 错误堆分配调度器无法管理其生命周期 Task* p_blink new BlinkTask(); // crash! // ❌ 错误局部变量函数返回后对象析构 void setup() { BlinkTask local_task; // 对象在 setup() 结束时销毁 Scheduler.start(local_task); // 悬空指针 }此约束源于调度器内部存储任务指针数组若任务对象生命周期短于调度器将导致野指针解引用。编译器链接阶段会将全局对象置于.data或.bss段确保其地址稳定。4. 典型应用示例解析4.1 基础 LED 闪烁任务Task#include Scheduler.h #include Task.h class BlinkTask : public Task { protected: void setup() override { pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW); } void loop() override { static uint8_t state LOW; // 静态局部变量维持状态 state !state; digitalWrite(LED_BUILTIN, state); delay(500); // 每 500ms 切换一次 } } blink_task; void setup() { Serial.begin(115200); Scheduler.start(blink_task); Scheduler.begin(); // 启动调度器 } // loop() 函数被忽略永不执行源码级解析delay(500)调用最终映射到AbstractTask::delay()更新nextRunTime成员变量调度器每次遍历时检查millis() nextRunTime满足则执行loop()static uint8_t state确保状态跨delay()调用持久化这是Task类的关键优势。4.2 内存监控任务LeanTask#include Scheduler.h #include LeanTask.h class MemTask : public LeanTask { public: void loop() override { Serial.print(Free Heap: ); Serial.print(ESP.getFreeHeap()); Serial.println( bytes); delay(10000); // 10秒后再次执行 } } mem_task; void setup() { Serial.begin(115200); Scheduler.start(mem_task); Scheduler.begin(); }关键差异分析无static变量需求loop()每次都是全新调用所有状态需存于类成员delay(10000)直接调用 Arduinodelay()但调度器会拦截并设置下次执行时间若需在delay()前执行耗时操作如网络请求必须确保其在loop()开头完成否则delay()将推迟整个周期。4.3 多任务协同Wi-Fi 连接管理 传感器采样#include Scheduler.h #include Task.h #include LeanTask.h // LeanTask轻量级 Wi-Fi 状态监控零栈 class WifiMonitor : public LeanTask { public: void loop() override { if (WiFi.status() ! WL_CONNECTED) { WiFi.begin(SSID, PASS); Serial.println(Connecting to WiFi...); } delay(2000); } } wifi_monitor; // Task需要状态机的传感器采样4KB 栈 class SensorTask : public Task { private: uint32_t lastRead 0; float temperature 0.0f; protected: void setup() override { // 初始化 I2C, 传感器校准等 Wire.begin(); } void loop() override { if (millis() - lastRead 1000) { // 每秒读取一次 temperature readDHT22(); // 模拟读取 lastRead millis(); // 发送数据到 MQTT可能耗时需 yield 让出 if (mqttClient.connected()) { mqttClient.publish(sensor/temp, String(temperature).c_str()); yield(); // 让出控制权避免阻塞其他任务 } } } } sensor_task; void setup() { Serial.begin(115200); WiFi.mode(WIFI_STA); Scheduler.start(wifi_monitor); // LeanTask零栈 Scheduler.start(sensor_task); // Task4KB 栈 Scheduler.begin(); }此例体现双轨设计的工程价值WifiMonitor作为高频、低复杂度任务使用LeanTask节省 RAMSensorTask因涉及 I2C 通信、MQTT 协议栈调用等潜在长延时操作必须使用Task以支持yield()中断恢复。5. 性能优化与调试指南5.1 RAM 使用实测对比官方测试数据揭示了核心优化价值固件任务构成Free Heap (bytes)RAM 节省分析simple.ino3 ×Task39,896基准线3×4KB12KB 栈开销lean_simple.ino1×Task 2×LeanTask48,1688,272 bytes相当于节省 2 个 Task 栈heap_test.ino(12 tasks)12×Task2,280严重不足WiFi 连接失败风险极高heap_test.ino(12 LeanTask)12×LeanTask51,91249,632 bytes可稳定运行复杂网络应用工程启示在 80KB RAM 的 ESP8266 上每增加 1 个Task实例即永久损失 4KB 可用 heap。对于需部署 5 功能模块的工业节点LeanTask是唯一可行选择。5.2 调试技巧与常见陷阱陷阱delay()在LeanTask中的位置错误// ❌ BAD第一次 delay() 后任务退出第二次 delay() 永不执行 class BadTask : public LeanTask { void loop() override { Serial.println(Start); delay(1000); // 此处 yield 给系统loop() 返回 Serial.println(End); // 永不打印 delay(1000); } };修复将逻辑合并为单次delay()或使用Task类。调试监控任务执行频率在loop()开头添加微秒计时void loop() override { static uint32_t last 0; uint32_t now micros(); Serial.printf(Task exec interval: %lu us\n, now - last); last now; // ... 任务逻辑 }优化减少millis()调用开销调度器内部频繁调用millis()若任务中需高精度计时可缓存void loop() override { static uint32_t base millis(); uint32_t now millis() - base; // 相对时间避免多次调用 }6. 与主流嵌入式生态集成6.1 FreeRTOS 共存方案ESP8266Scheduler 可与 FreeRTOS 共存但需明确分工FreeRTOS管理高优先级、硬实时任务如音频解码、电机 PID 控制ESP8266Scheduler管理低优先级、软实时任务如 Web 服务器、OTA、日志上传。通过xTaskCreate()创建 FreeRTOS 任务在其taskFunction中启动Scheduler.begin()void schedulerTask(void* pvParameters) { Scheduler.start(web_server_task); Scheduler.start(ota_task); Scheduler.begin(); // 此处阻塞但 FreeRTOS 允许其他任务运行 } void setup() { xTaskCreate(schedulerTask, SCHEDULER, 4096, NULL, 1, NULL); }6.2 Arduino HAL 驱动兼容性所有 Arduino 标准 APIdigitalWrite,analogRead,Wire.*,SPI.*均可在Task::loop()中直接使用。yield()会触发 Arduino Core 的handlePendingInterrupts()确保millis()、micros()、Serial缓冲区等正常工作。唯一限制是避免在Task::loop()中调用WiFi.disconnect()等可能触发长时阻塞的 API应改用异步回调模式。7. 工程选型决策树面对具体项目需求按此流程决策评估 RAM 预算ESP.getFreeHeap()启动后 20KB→ 强制使用LeanTask分析任务复杂度是否需递归、深度函数调用、大数组局部变量→ 必须Task检查时序要求任务执行时间是否稳定 5ms→LeanTask安全否则Taskyield()分片验证外设驱动所用传感器库是否含阻塞delay()→ 若是封装为Task并替换为yield()最终验证编译后查看.map文件确认.bss段未溢出 RAM 限制。在 ESP8266-12F4MB Flash/80KB RAM上一个典型工业网关固件配置为1×TaskMQTT 客户端 3×LeanTask温湿度、继电器控制、LED 指示Free Heap 稳定维持在 42KB足以为 BearSSL TLS 握手预留空间。

相关文章:

ESP8266轻量协程调度器:零栈LeanTask与确定性多任务设计

1. 项目概述ESP8266Scheduler 是一个专为 ESP8266 平台设计的协作式多任务调度器(Co-operative Multitasking Scheduler),其核心目标是在资源受限的 Wi-Fi SoC 上实现轻量、确定、可预测的任务并发执行模型,同时避免传统抢占式 RT…...

Splitting.js创意指南:让网页文字动起来的实用技巧

Splitting.js创意指南:让网页文字动起来的实用技巧 【免费下载链接】Splitting JavaScript microlibrary to split an element by words, characters, children and more, populated with CSS variables! 项目地址: https://gitcode.com/gh_mirrors/sp/Splitting …...

203 异构车辆队列分布式 MPC 优化控制约束复现之旅

203 异构车辆队列分布式 MPC 优化控制约束 复现的代码 .m 文件在自动驾驶和智能交通领域,异构车辆队列的分布式模型预测控制(MPC)是个热门话题。今天就来聊聊基于复现代码(.m文件)对203异构车辆队列分布式MPC优化控制约…...

探索液晶仿真负折射的奇妙世界

液晶仿真负折射在光学和材料科学领域,负折射现象一直是一个令人着迷的研究方向。而通过液晶来进行负折射的仿真,更是为这个领域带来了新的活力和可能性。 什么是负折射 通常情况下,当光线从一种介质进入另一种介质时,遵循斯涅尔定…...

嵌入式系统模块化设计:内聚与耦合实战指南

1. 嵌入式模块设计的核心原则在嵌入式系统开发中,模块化设计质量直接影响着整个系统的生命周期成本。我经历过多个嵌入式项目后发现,那些后期维护成本高昂的系统,往往都存在模块边界模糊、依赖混乱的问题。模块化不是简单的代码分割&#xff…...

Polars 2.0清洗卡顿?,一文讲透Arrow IPC缓存、predicate pushdown与schema inference协同配置逻辑

第一章:Polars 2.0清洗卡顿现象的根因诊断Polars 2.0 在大规模数据清洗场景中偶发的卡顿并非源于计算能力不足,而是由内存管理策略变更与惰性执行链中隐式物化点触发不当共同导致。核心问题集中在 lazy() 查询计划在遭遇特定 I/O 模式或类型推断失败时&a…...

从模板到成品:5分钟搞定Java动态填充Word合同(基于Apache POI和DOCX模板)

从模板到成品:5分钟搞定Java动态填充Word合同(基于Apache POI和DOCX模板) 每次手动调整Word格式就像在玩“大家来找茬”——明明只是改个客户名称,整个文档排版却突然崩坏。去年我们团队处理了超过2000份合同,直到发现…...

十字头零件的机械加工工艺规程及工装夹具设计 (论文+CAD图纸+任务书+过程卡+工序卡+外文翻译+参考文献……)

十字头零件作为机械传动系统中的关键构件,其加工精度直接影响设备运行的稳定性与寿命。制定科学合理的机械加工工艺规程及配套工装夹具设计方案,是确保零件质量、提升加工效率的核心环节。工艺规程需系统规划从毛坯准备到成品检验的全流程,涵…...

硬件工程师成长指南:从理论到实战的完整路径

1. 硬件工程师的成长路线:从理论到实践的完整规划作为一名从业十年的硬件工程师,我见过太多新人一上来就埋头焊板子、调电路,结果浪费大量时间在低水平重复。硬件设计就像下围棋,没有全局思维的人永远只能当个业余爱好者。今天我想…...

动态链接库emp.dll详解:从原理到实战修复

动态链接库emp.dll深度解析:技术原理与高效修复指南 引言:动态链接库的现代价值 在Windows系统的软件生态中,动态链接库(DLL)如同建筑中的预制构件,通过代码复用机制显著提升了开发效率和系统资源利用率。emp.dll作为其中一员&…...

Python程序员转战Mojo的最后1公里:自动转换工具mojoify上线首周已修复89%语法迁移阻塞点(限时开源)

第一章:Mojo与Python混合编程全景概览Mojo 是一种为 AI 系统量身打造的现代系统编程语言,兼具 Python 的易用性与 C/Rust 的执行效率。它原生兼容 Python 生态,允许开发者在同一个项目中无缝调用 Python 模块、复用 NumPy/Torch 接口&#xf…...

超越简单拼接:如何用SuperFusion的语义约束,让你的图像融合结果直接服务于目标检测与分割?

超越简单拼接:语义约束如何重塑图像融合的下游任务价值 当红外与可见光图像在自动驾驶感知系统中相遇时,工程师们往往面临一个两难选择:追求视觉上自然的融合效果,还是确保关键目标特征能被检测算法准确识别?传统融合方…...

SOONet模型Python从入门到集成:环境配置与核心调用

SOONet模型Python从入门到集成:环境配置与核心调用 如果你刚接触AI模型,想用Python把SOONet这样的模型跑起来,可能会觉得有点无从下手。环境怎么配?依赖库怎么装?模型文件放哪里?代码怎么写?这…...

暗黑破坏神2终极单机插件:PlugY生存工具包完全指南

暗黑破坏神2终极单机插件:PlugY生存工具包完全指南 【免费下载链接】PlugY PlugY, The Survival Kit - Plug-in for Diablo II Lord of Destruction 项目地址: https://gitcode.com/gh_mirrors/pl/PlugY 如果你是一名暗黑破坏神2的单机玩家,是否曾…...

Python实战:用SymPy解常微分方程 vs 偏微分方程的5个关键差异

Python实战:用SymPy解常微分方程 vs 偏微分方程的5个关键差异 微分方程是数学建模的核心工具,而Python的SymPy库让符号计算变得触手可及。但当你真正在Jupyter Notebook中敲下dsolve()命令时,是否困惑过为什么有些方程秒出结果,有…...

探索kedro:数据科学项目的高效管理框架

探索kedro:数据科学项目的高效管理框架 【免费下载链接】kedro Kedro is a toolbox for production-ready data science. It uses software engineering best practices to help you create data engineering and data science pipelines that are reproducible, ma…...

aibye爱毕业推出六大顶尖平台评测,智能润色与高效创作功能一键实现,科研领域不可或缺的AI助手

工具名称 核心功能 特色优势 Aibiye 论文生成降AI率 全学科覆盖、仿写优化、自动图表生成 Aicheck AI检测文献综述辅助 精准查新、3分钟高效成文 GPT学术版 润色/翻译/代码解释 多模型协同、PDF深度解析 摆平论文 大纲生成降重改写 三步出稿、本硕博通用 QuillB…...

Arduino LSM6DS3驱动库深度解析:寄存器级IMU开发指南

1. Arduino_LSM6DS3库深度解析:面向嵌入式工程师的LSM6DS3惯性测量单元驱动开发指南 1.1 库定位与工程价值 Arduino_LSM6DS3是专为Arduino Nano 33 IoT和Arduino Uno WiFi Rev2两款板卡设计的LSM6DS3惯性测量单元(IMU)驱动库。该库并非通用型…...

Python 算法详解:从原理到实践

Python 算法详解:从原理到实践 1. 背景与动机 算法是计算机科学的核心,它是解决问题的步骤和方法。Python 作为一种功能强大的编程语言,提供了丰富的工具和库来实现各种算法。掌握 Python 算法不仅可以提高程序的效率,还可以培养解…...

爱毕业aibye发布六大权威平台排名,智能改写与高效写作功能一键完成,科研必备的AI工具

工具名称 核心功能 特色优势 Aibiye 论文生成降AI率 全学科覆盖、仿写优化、自动图表生成 Aicheck AI检测文献综述辅助 精准查新、3分钟高效成文 GPT学术版 润色/翻译/代码解释 多模型协同、PDF深度解析 摆平论文 大纲生成降重改写 三步出稿、本硕博通用 QuillB…...

ArdaTask:面向MCU的轻量级时间驱动任务调度框架

1. 项目概述ArdaTask 是一个面向嵌入式系统的轻量级、时间驱动型多任务调度框架,其设计目标明确:在资源受限的MCU(如Cortex-M0/M3/M4、RISC-V内核)上实现确定性、低开销、无动态内存分配的周期性任务管理。它不替代RTOS&#xff0…...

ROS2数据录制实战:用ros2 bag记录小海龟运动轨迹(附常见问题排查)

ROS2数据录制实战:从入门到精通的ros2 bag全指南 小海龟在屏幕上划出优美轨迹的瞬间,你是否想过如何完整记录这些运动数据?ROS2中的ros2 bag工具正是为解决这类需求而生。作为机器人开发中的数据"时光机",它不仅能忠实记…...

Adafruit MAX44009库详解:超低功耗环境光传感器驱动与工程实践

1. 项目概述Adafruit MAX44009 库是专为 Analog Devices(原 Maxim Integrated)推出的 MAX44009 环境光传感器设计的 Arduino 兼容驱动库。该库封装了 IC 通信、寄存器配置、自动量程切换、中断管理及光照度(lux)换算等底层逻辑&am…...

Ubuntu 23.04 避坑指南:pip install virtualenv 报错 extern-managed-environment 的3种解决方案

Ubuntu 23.04 Python包管理新规深度解析:安全与灵活性的平衡之道 最近升级到Ubuntu 23.04的Python开发者们可能遇到了一个令人困惑的新错误——当尝试使用pip install安装包时,系统会抛出"externally-managed-environment"的警告并拒绝执行。这…...

嵌入式开发问题解决:从复现到根治的实战指南

1. 嵌入式开发问题解决之道:从复现到根治 搞嵌入式开发这些年,踩过的坑比写过的代码还多。每次遇到系统崩溃、数据异常或者外设抽风,都像在玩侦探游戏——证据支离破碎,真凶隐藏极深。今天就把我这些年总结的"破案"方法…...

LFM2.5-1.2B-Thinking效果实测:Ollama中对比Qwen2-1.5B/Llama3-1B生成质量

LFM2.5-1.2B-Thinking效果实测:Ollama中对比Qwen2-1.5B/Llama3-1B生成质量 1. 测试背景与模型介绍 最近在Ollama平台上测试了一款很有意思的小模型——LFM2.5-1.2B-Thinking。这个模型虽然只有12亿参数,但号称能在设备端实现接近大模型的性能。为了验证…...

小白程序员必看:收藏这份RAG大模型核心技术原理详解,轻松入门智能Agent

1. 核心流程全景图RAG 的生命周期可以严格划分为两个平行的工作流:离线数据处理流(Data Pipeline) 和 在线检索生成流(Query Pipeline)。RAG 核心工作流 1.1 离线数据处理流(Data Ingestion) 这…...

我国网络安全行业前景如何?是否可以入行?有哪些岗位?

我国网络安全行业前景如何?是否可以入行?有哪些岗位? 网络空间安全专业简称“网络安全专业”,主要以信息构建的各种空间领域为主要研究对象,包括网络空间的组成、形态、安全、管理等。我国网络空间安全专业于2015年设立…...

【黑客必看】2025最新kali Linux安装教程(超详细),看这一篇就够了

【黑客必看】2025最新kali Linux安装教程(超详细),看这一篇就够了 【黑客必看】kali Linux安装教程(超详细),看这一篇就够了! 一、镜像下载 官网镜像链接:https://cdimage.kali.org/…...

黑客入侵终端设备的五种常见方式

黑客入侵终端设备的五种常见方式 网络安全重磅福利:入门&进阶全套282G学习资源包免费分享! 黑客的攻击方式并非都是复杂繁琐的。当黑客发起网络攻击时仅为了牟利而已,并不是都需要掌握高超的技术。他们的动机大体上可以分为两种&#xff…...