LuatOS消息列表机制:事件驱动与初始化顺序实战解析
做嵌入式开发的同学尤其是玩过基于Lua的物联网模组的人多半有这样一种体验业务代码写得飞快但一到多任务协作、事件响应、模块解耦就总觉得哪里不对劲。回调套回调、全局变量满天飞偶尔一个状态没同步就出现“时好时坏”的灵异问题。后来我把LuatOS的系统消息列表真正吃透才发现之前遇到的大部分问题根子都在于事件没有走同一条路。LuatOS这套框架的核心引擎就是用一张系统消息列表把硬件中断、定时器、网络事件、协程等待全部收拢再按主题分发给对应的业务回调。这篇东西不打算复述文档里的API而是重点拆解消息列表的初始化过程和它在实战里的应用方式想清楚开机后那几毫秒发生了什么、为什么订阅时机那么敏感以及日常业务怎么写才不容易翻车。如果你准备在LuatOS上做多外设、多状态的中大型项目这篇应该能帮你省掉不少排查时间。1. 为什么要从消息列表讲起1.1 事件驱动不是新概念难的是在嵌入式里落地桌面开发里搞事件驱动很常见点击按钮、鼠标移动、网络返回每一类事件都有对应的处理入口。但嵌入式环境有其特殊性裸机或轻量RTOS下整个系统基本是一条主线程中断上下文极其受限你不能在中断里打日志、做延时、申请大块内存更不允许让一个驱动回调去阻塞主流程。这时候就需要一个“中间层”把中断和业务彻底隔开。拿现实生活打个比方一个公司有很多部门外部来电要转给对口的负责人。如果你让每个外部客户直接记着十几个部门的分机号那客户一多肯定乱套。于是公司设了前台总机所有来电先到总机总机根据来电意图转发到对应分机。消息列表在LuatOS里干的就是总机的活所有事件先收拢到一个统一入口再根据主题分发到订阅它的业务函数。呼叫方不需要知道接收方是谁接收方也不需要知道消息从哪来这就是解耦。对比初学者常用的“全局flag”方案消息列表的优势在于事件有了统一的缓冲区不会因为某个回调还没来得及读flag就把状态覆盖掉订阅关系集中管理代码可读性高底层驱动和应用层不再互相依赖驱动坏了换新驱动业务代码不用动。1.2 消息列表在整个系统里扮演的角色LuatOS应用层跑着Lua虚拟机底层仍然是RTOS和驱动。正常情况下一个典型项目的启动流程是main.lua里require sys注册若干task和定时器最后调用sys.run()进入主循环。但这个主循环不是简单地死等它每转一圈都要去取底层产生的消息再决定分发给谁。消息列表就是连接“底层事件”和“业务回调”的那条传送带。比如串口收到一帧数据底层驱动产生一个事件这个消息被塞进列表主循环把事件取出来按主题找到订阅了该主题的回调把数据传进去执行。UART是这样GPIO中断、定时器到期、网络状态变化也都是这样。理解了这条传送带整个LuatOS的运行机制就通了一半。1.3 谁该花时间把这套机制吃透如果你只是点个灯、读个温湿度那确实不需要深究消息列表直接顺序调用就行。但一旦你开始做量产级项目多路传感器、MQTT上报、低功耗唤醒、断网重连、多个业务task并发这套机制就是你绕不开的地基。我建议至少掌握三层一是订阅和发布怎么配对二是消息列表初始化时做了什么三是如何在多个task里用waitUntil做同步。把这三层想清楚了后面写业务会非常顺手。2. 系统消息列表的完整初始化流程解析2.1 初始化到底建了什么队列表与订阅表很多新手以为“初始化消息列表”就是执行个kernel.init其实没那么简单。它在内存里主要建了两张表订阅表和消息队列。订阅表一个以topic为key、以回调函数列表为value的table。消息队列一个先进先出的数组存放待处理的事件。我用一个简化版的Lua模型来说明方便理解内部机制local sys {} -- 消息队列先进先出 local msgQueue {} -- 订阅表topic - { cb1, cb2, ... } local subTable {} function sys.init() msgQueue {} subTable {} -- 在真正系统里还要做rtos消息接收回调的注册 log.info(sys.init, message list ready) end -- 把事件加入队列 local function enqueue(topic, ...) table.insert(msgQueue, { topic topic, args { ... } }) end -- 从队列取出一个事件并分发给订阅者 local function dispatch(msg) local cbs subTable[msg.topic] if cbs then for _, cb in ipairs(cbs) do cb(table.unpack(msg.args)) end end end真正的LuatOS源码比这个复杂得多还牵扯协程调度和定时器但骨架就是这个思路。注意一个关键点订阅表是以主题为key的发布的任何消息都要先查这张表。如果表里没有对应主题消息要么丢弃要么走默认处理不会凭空冒出一个回调来执行。2.2 把硬件中断变成sys消息的关键一步消息列表初始化时有一件事容易被忽略底层驱动的回调必须在这个阶段注册好。也就是说系统要告诉底层“你有了中断、收到了数据别直接去调用业务先把事件送到我指定的入口”。为什么要转这一手因为中断上下文不适合也最好不要跑业务逻辑。中断处理器对时间要求极严格一个大循环卡在中断里整个系统可能就“死”了。中断里能做的基本只是保存现场、把事件丢出去。消息列表起到的就是“变压器”作用从高压的中断环境变成低压的普通任务环境让业务代码能安全地处理同样的信息。在LuatOS实际工程里我们不会自己写rtos级别的回调直接用官方封装好的库就行。但我强烈建议你了解这条链路硬件中断 - RTOS消息 - sys.run主循环取消息 - 按主题分发。很多开发者在排查“串口丢数据”“按键反应慢”时真正的问题不是业务代码而是对这条链路的时序理解不到位。2.3 初始化顺序为什么不能乱来初始化顺序里藏着三个最容易踩的坑我按重要性排序第一消息列表本体必须先于底层回调注册存在。道理很简单回调来了消息列表还不存在事件往哪放事件丢了后面业务怎么等都等不到。第二业务订阅要尽量早最好在对应模块启动前完成。比如网络模块刚连上就publish一个“NET_READY”你的订阅代码如果在publish之后才执行那这个消息就错过了。时序敏感的项目最稳妥的做法是订阅关系放在模块初始化的最前面宁可比实际使用早一点也不要晚。第三sys.run之前的require顺序要稳定。很多项目把require塞在main.lua里顺序随意今天能用明天不行。我建议把依赖关系理清楚基础组件、驱动、业务模块、订阅初始化从上到下加载形成一个固定的初始化顺序。听起来是洁癖但在复杂项目里能省下一半的排查时间。3. 订阅、发布与等待三大核心操作实战3.1 sys.publish 与 sys.subscribe 的配对使用这是消息列表最基础的用法一行发布、一行订阅。以网络状态通知为例-- 模块A检测到网络连接成功后广播状态 sys.publish(NET_READY, ip_addr) -- 模块B关心网络状态提前订阅 sys.subscribe(NET_READY, function(ip) log.info(net, ready, ip .. (ip or )) end)subscribe去订阅表里登记一个topic对应的回调publish往消息列表里丢一个事件主循环取出来后依次调用这个topic下的所有回调。发布方不需要知道有几个订阅者订阅方也不需要知道是谁发的这就是事件总线的松散耦合。主题命名有个实用建议用“模块名_事件”这种下划线风格比如“UART_DATA_READY”“BUTTON_PRESSED”“OTA_RESULT”命名越规范后期全局搜索越省事。我见过有人用中文主题能跑但建议不要日志和排查都很别扭。参数传递上publish可以带多个参数。你可以在回调里放心使用可变参数因为table.unpack会把所有参数展开。但很多实践里我发现参数传太多会让调用关系变得难追如果业务数据复杂更好的做法是传一个table或对象引用而不是一堆散装参数。3.2 一次性且阻塞式的等待waitUntil 与 subscribeWait在实际项目里更常见的需求不是“事件来了就处理”而是“我这件事要等到某个事件发生了再继续”。比如某个task要等串口回包、等网络断开重连完成、等某个外设就绪。这时候用订阅回调不方便因为在回调里只能做“回调里的事情”很难让写在中途的业务代码停下来等待。LuatOS为此提供了一种协同式的等待方式。以等待网络底层某个事件为例sys.taskInit(function() log.info(test, wait for network ready) local ip sys.waitUntil(NET_READY, 3000) if ip then log.info(test, network ok, ip .. ip) else log.warn(test, network timeout) end end)waitUntil的语义是当前协程挂起直到指定主题收到消息或等到超时。它只关心“收到这个主题”不执行订阅回调而是把消息内容直接作为返回值交给当前任务。这就把异步事件变成了同步代码非常符合人的直线思维。subscribeWait则可以理解为“一次性订阅”收到一次消息后自动取消订阅并执行回调。它适合那种只关心一次结果的场景比如查询一次设备状态sys.subscribeWait(SENSOR_READY, function(data) log.info(sensor, ready, data, data) end, 2000)这里的超时参数是可选的但我建议一定要给。没有超时消息一直不来订阅就一直挂着。如果系统反复创建这种订阅内存和回调数量都会膨胀最终表现为各种诡异问题。给超时至少有个兜底。3.3 订阅生命周期管理什么时机订阅什么时机退订LuatOS不同历史版本的订阅管理API略有差异有的提供退订函数有的没有。但有一个原则是通用的任何订阅都必须有清晰的生命周期。如果这个订阅是模块级别的整个生命周期都在那就在模块初始化时订阅一次不要重复执行。如果这个订阅是任务级的用一次就完优先选waitUntil或subscribeWait让系统自动处理取消。如果框架版本能手动退订在模块进入休眠、销毁前记得退订避免消息还在分发但处理对象已经无效。还有一个常被忽略的坑两个模块各自定义了相同名字的主题订阅关系会互相干扰。主题是全局的没有命名空间隔离所以命名一定要全局唯一。我的习惯是统一加模块前缀避免“LOG”“STATE”这种过于通用的话题引发冲突。4. 实战把一套环境监测系统改造成消息驱动4.1 需求与模块划分假设现在要做一个小型环境监测Demo硬件上有温湿度传感器、一个按键、一个NB-IoT网络模块需求是每60秒读一次温湿度按键按下后立即读取并上报一次网络断开时数据先缓存到本地等重连后再补报。如果不用消息列表代码很容易写成传感器模块直接调用网络模块的上报函数按键模块在中断回调里又去调传感器传感器回调里还去调日志和网络模块之间形成蛛网状依赖。用消息驱动后我建议这样划分传感器模块定期发布“DATA_READY”消息内容为温湿度数据。按键模块按键事件发布“BUTTON_PRESS”消息。网络模块订阅这两个主题拿到数据后负责上报网络状态变化时发布“NET_READY”或“NET_LOST”。4.2 初始化与主程序落地先看初始化部分顺序必须稳住local sys require(sys) require(sensorDriver) -- 传感器底层驱动 require(netModule) -- 网络模块 require(appLogic) -- 业务逻辑 -- 在这里统一注册订阅关系 sys.subscribe(DATA_READY, function(temp, humi) netModule.report(temp, humi) end) sys.subscribe(BUTTON_PRESS, function() local temp, humi sensorDriver.read() netModule.report(temp, humi) end) sys.run()再看业务任务sys.taskInit(function() while true do local temp, humi sensorDriver.read() -- 发布消息让关心数据的模块去处理 sys.publish(DATA_READY, temp, humi) sys.wait(60000) end end)按键模块放在另一个task里按下按键发布事件sys.taskInit(function() while true do local key keyPad.waitKey(0) if key 1 then sys.publish(BUTTON_PRESS) end end end)这个结构的好处一眼就能看出来传感器任务不需要知道“数据要被网络上报”只管发布网络模块也不需要自己定时读传感器订阅到了数据再执行即可。以后想加一个OLED显示模块只需要再订阅一次“DATA_READY”完全不动现有代码。4.3 一次完整事件的血流图我用自己的习惯把这个流程口述一遍这比文字表格更直观按键按下 - 驱动层检测到GPIO电平变化 - 底层中断注册的入口把事件转成消息 - sys.run主循环取到消息 - 根据主题“BUTTON_PRESS”找到两个订阅者一个是立即上报逻辑另一个可能是OLED显示提示之类- 回调依次执行。整个过程从硬件中断到业务回调没有跨模块直接调用每一层都清晰可控。核心体验是一旦你习惯了这种思维调试问题会变得特别痛快。出问题先问“消息发了吗主题对吗有人订阅吗”很快就能定位而不是在几层回调里翻来覆去找谁调用了谁。4.4 消息驱动的收益与边界消息驱动不是万能药我在项目里也吃过它的亏。高吞吐场景下比如音频数据流、高速流水线数据每一条都走消息发布回调查表、入队、出队的开销就不是可以忽略的了。这时候更适合直接把数据通过驱动回调传给专用缓冲让专属task去消费。还有一类场景要小心对执行顺序高度敏感的状态机。比如两个消息都订阅了同一个主题但A消息必须严格先于B消息执行这时候单纯依赖订阅顺序不稳定。解决办法是让订阅回调只做对应的状态推进或者把状态机收敛到单一task里用waitUntil消费消息序列。消息列表适合做解耦但不适合当作严谨排序的同步工具。5. 常见问题与排查技巧实录5.1 消息丢失先查时序再查订阅遇到“我发了消息但回调不执行”九成是时序问题。最常见的两种第一种发布早了订阅晚。业务代码在subscribe之前就publish等订阅建立消息已经分发完被丢弃了。解决方法是把订阅放在初始化阶段或者在事件产生前先检查标志。如果在main.lua里先require了业务模块模块内发布后执行订阅就会复现这个问题。第二种主题名不一致。这不是玩笑我见过有人发布“NET_READY”订阅“NET_READY_”排查了很久才发现多了一个字符。主题是字符串没有编译器帮你查错建议在调试阶段统一打印一份主题列表或者写个工具函数统一管理主题常量不要各自手写字符串。5.2 回调里做耗时操作导致消息堆积消息列表按顺序分发一个回调如果卡住后续所有事件都会排队。我遇到一个现场某模块的网络回调里直接做了阻塞式FLASH写入一个周期接近300毫秒结果按键事件排队排到延迟几秒才响应。正确做法是回调只做必要的事情。如果处理确实耗时就把数据放入一个队列另起一个task专门消费这个队列。回调里置个标志位耗时任务在task里等待标志位出现再执行主循环就能保持轻快。local shouldSave false sys.subscribe(DATA_READY, function(temp, humi) shouldSave true cacheTemp temp cacheHumi humi end) sys.taskInit(function() while true do sys.waitUntil(SAVE_SLOT, 200) if shouldSave then flashWrite(cacheTemp, cacheHumi) shouldSave false end end end)这样回调执行时间极短耗时操作被挪到任务里不会堵塞消息分发。5.3 重复订阅导致回调执行两次模块被require了两次或者代码在循环里反复直接调用subscribe都会导致回调重复执行。LuatOS的subscribe默认是追加式的同一个topic订阅同一函数订阅几次就执行几次。这种问题表面症状是“数据重复上报”“串口发了两遍”很误导人。排查思路是在订阅回调第一行加个追踪日志或者全局搜索subscribe的位置检查是否在循环、定时器里被反复调用。另外模块加载统一放到main.lua集中管理避免多个文件互相require同一模块能大幅降低重复订阅概率。5.4 调试消息列表的实用土办法说实话最有效的调试方法不是看文档而是给消息列表包一层日志。我在项目里习惯写一个小工具把所有publish和subscribe的调用都打印出来包含主题名、参数数量、回调触发时间。这个工具平时关闭排查问题时通过log开关打开几秒钟就能看到时序是否符合预期。注意量产阶段一定要关闭这个日志否则日志本身会成为性能瓶颈在高频事件场景下尤为明显。另外在周期性任务里打印消息队列长度可以快速判断是否堆积。如果队列长度一直增长基本可以认为“消费速度跟不上生产速度”直接去查回调里有没有阻塞即可。5.5 休眠唤醒与消息配合的注意事项低功耗场景是消息列表最容易踩坑的地方。MCU进入休眠后消息列表里的定时器和队列并不会自动跑必须设计成“事件触发式唤醒”。我的一般做法是在发布关键事件之前先保证订阅方已完成唤醒再发布主题。如果顺序反过来唤醒还没完成消息就已经分发完了订阅方收不到。其次在休眠前的初始化阶段把会立即触发的订阅先关掉避免唤醒瞬间消息蜂拥而至。6. 踩坑心得这几年在多个LuatOS项目里反复验证我最大的体会是消息列表这套机制最容易被忽略、但最值得认真对待的地方恰恰是初始化阶段。项目定位越复杂初始化顺序的影响就越明显。我现在养成了一个习惯新工程动工先不写业务逻辑先画一张订阅关系表标明每个模块几点发、谁在收、谁先加载。画清楚了代码就是在填表画不清楚后期排查问题全靠运气。另一个心得是消息列表的API学习成本很低真正的门槛是设计思维。很多开发者转型LuatOS时还在用“所有函数直接调用”的裸机思维这没问题但在多模块项目里会让代码走向崩溃。试着把业务拆成“生产者”和“消费者”用主题把它们串起来代码结构会瞬间清爽很多。如果你还想把这套机制玩得更深可以自己封装一层更上层的业务事件总线在主题里加入系统状态前缀或者给关键消息增加一次性的缓存这样订阅方在迟订阅时也能拿到最近一次的消息状态。这个方向在实际项目里非常实用后续有机会我再展开聊聊。

相关新闻

双平台开发工程师实战指南:iOS/Android技术栈与高频问题排查

双平台开发工程师实战指南:iOS/Android技术栈与高频问题排查

1. 双平台开发岗位全景:职责边界与能力模型这两年移动开发的招聘需求有个明显变化:很多团队不再单独招“iOS工程师”或“Android工程师”,而是直接写“双平台开发工程师”。甚至有些中小型公司,一个移动端岗位要同时覆盖iOS、Andr…

2026/10/11 21:37:31 阅读更多 →
蟑螂检测数据集VOC/YOLO双格式解析与YOLOv8训练实践

蟑螂检测数据集VOC/YOLO双格式解析与YOLOv8训练实践

简介:面向计算机视觉目标检测需求,这份数据包适合需要训练蟑螂识别模型的开发者、算法学习者以及智能家居或卫生防治项目人员。资源包含三百七十四张真实环境蟑螂图片,配套相同数量的XML标注文件与TXT标注文件,XML遵循Pascal VOC格…

2026/10/11 21:36:30 阅读更多 →
--cached 只删 Git 记录,不删本地 node_modules。之后 Git 不会再追踪它。删除线上仓库的node_modules

--cached 只删 Git 记录,不删本地 node_modules。之后 Git 不会再追踪它。删除线上仓库的node_modules

项目根目录新建或编辑 .gitignore,加入:/gitignorenode_modules/终端执行,把 node_modules 从 Git 索引中移除(保留本地文件):git rm -r --cached node_modules提交并推送:git add . git commit…

2026/10/11 21:36:30 阅读更多 →

最新新闻

基于Solidworks的土豆去皮机三维设计流程与避坑指南

基于Solidworks的土豆去皮机三维设计流程与避坑指南

简介:基于Solidworks的土豆去皮机三维设计文档,面向机械设计及自动化专业学生、毕业设计或课程设计人员,以及餐饮设备研发人员。文档围绕中小型饭店、宾馆等餐饮场所的土豆预处理需求,完成了一款经济实用型去皮机的整机设计&#…

2026/10/12 0:06:02 阅读更多 →
上海大学答辩通用PPT模板:从母版版式到配色字体的参数化设计

上海大学答辩通用PPT模板:从母版版式到配色字体的参数化设计

简介:专为上海大学学生设计的通用答辩PPT模板,覆盖毕业答辩、学术汇报、开题答辩与周会汇报等场景。模板内置清晰的目录结构、标题页、多种内容版式与图表展示模块,标题页预留汇报人、指导老师、时间等基本信息位;章节标题可参考模…

2026/10/12 0:06:02 阅读更多 →
CAD-VBA二次开发实战:从ActiveX对象模型到批量自动化

CAD-VBA二次开发实战:从ActiveX对象模型到批量自动化

简介:《CAD-VBA开发人员手册》是面向AutoCAD二次开发初学者与进阶VBA开发者编写的实用技术指南,作者解祥成。全书共十章,从VBA入门、嵌入与全局工程管理、宏处理讲起,逐步深入ActiveX自动操作基础、AutoCAD对象模型与集合对象操作…

2026/10/12 0:06:01 阅读更多 →
绝缘子缺陷检测数据集清洗与工业级训练实战指南

绝缘子缺陷检测数据集清洗与工业级训练实战指南

简介:本资源是面向电力AI研发人员、工业视觉工程师及智能巡检系统开发者的绝缘子缺陷检测专用YOLO格式数据集,解决无人机航拍场景下绝缘子破损、污闪、积雪等9类典型缺陷的精准识别与定位难题。数据集共2139张真实巡检图像(含训练/验证/测试集…

2026/10/12 0:05:01 阅读更多 →
牙科影像龋齿四级像素级分割数据集与临床落地实践

牙科影像龋齿四级像素级分割数据集与临床落地实践

简介:本资源是一套面向医学影像AI研究者与口腔临床算法开发者的专业蛀牙分割数据集,专为U-Net、DeepLab等分割模型训练设计,解决真实场景下多类别蛀牙区域精细识别与程度量化评估难题。数据集含400张高精度口腔内窥镜及X光影像(对…

2026/10/12 0:05:01 阅读更多 →
条形码目标检测数据集实战:从YOLOv8训练到部署

条形码目标检测数据集实战:从YOLOv8训练到部署

简介:这是一份面向目标检测与计算机视觉学习者的条形码识别数据集,涵盖零售、物流、制造等场景下的真实商品条码图像,适合用于训练YOLO系列模型或开展算法实验。数据集共684张图片,按训练集624张、验证集60张划分,采用…

2026/10/12 0:04:01 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →