【实时Linux核心技术:从概念到实战】06:编写你的第一个实时线程:API详解与注意事项
摘要:在汽车电子、工业控制、机器人等领域,系统的确定性往往比平均性能更重要。本文从实时性的本质出发,详解如何基于Linux POSIX实时扩展,从零编写一个具备确定性周期的实时线程。我们将深入剖析pthread实时属性的正确配置流程,特别是被无数人忽略的PTHREAD_EXPLICIT_SCHED陷阱;掌握用clock_nanosleep实现微秒级精确周期控制的诀窍;并手把手带你完成mlockall防页面抖动、CPU亲和性绑核、堆栈预热等关键系统级调优。文章提供一个完整、可编译运行的测试程序,并基于cyclictest进行性能基线对比。最后,结合我自己的踩坑经历,梳理了9个线上环境中高频出现的致命错误及规避方案。读完本文,你不仅能写出“能用”的实时线程,更能写出一个抖动在微秒级、值得信赖的实时任务基座。优质专栏欢迎订阅!【OpenClaw从入门到精通】【DeepSeek深度应用】【Python高阶开发:AI自动化与数据工程实战】【YOLOv11工业级实战】【机器视觉:C# + HALCON】【软件设计师·软考50讲通关|从零基础到工程师职称】【人工智能之深度学习】【AI 赋能:Python 人工智能应用实战】【数字孪生与仿真技术实战指南】【YOLOv8/v9/v10 实战与工业部署】【C#工业上位机高级应用:高并发通信+性能优化】【Java生产级避坑指南:高并发+性能调优终极实战】【Coze搞钱实战:零代码打造吸金AI助手】【YOLO26核心改进+场景落地实战宝典】【OpenClaw企业级智能体实战】文章目录【实时Linux核心技术:从概念到实战】06:编写你的第一个实时线程:API详解与注意事项1. 实时线程的“特权”本质:调度策略与优先级2. Pthread属性配置:四步走,一步都不能少2.1 第一步:初始化属性对象2.2 第二步:设置调度策略2.3 第三步:设置调度参数(优先级)2.4 最关键的一步:设置继承策略,**PTHREAD_EXPLICIT_SCHED**2.5 验证配置:眼见为实3. 周期的节拍器:`clock_nanosleep`与精确唤醒3.1 `sleep()`和`nanosleep()`为什么不行?3.2 `clock_nanosleep`的使用诀窍3.3 处理信号中断(`EINTR`)和任务超期3.4 多任务场景下的备选方案4. 系统级“排雷”三件套:内存、CPU、堆栈4.1 排雷一:用`mlockall`把内存“焊死”4.2 排雷二:绑定CPU,独占一核4.3 排雷三:预设堆栈,杜绝“首次”缺页5. 完整示例:打造一个性能可量化的周期心跳6. 那些年我踩过的坑:实时线程的9大雷区6.1 雷区一:`PTHREAD_INHERIT_SCHED`,静默的杀手6.2 雷区二:在实时循环里“引爆炸弹”——`printf`6.3 雷区三:用`nanosleep`等相对时间接口6.4 雷区四:无视`EINTR`,周期大乱6.5 雷区五:`mlockall`失败,或者锁了个寂寞6.6 雷区六:栈太小,或者没“踩”6.7 雷区七:跟优先级反转打照面6.8 雷区八:用错时钟,错把“现实”当“单调”6.9 雷区九:跑在虚拟机/容器里测实时性7. 性能验证与调优:不要相信感觉,要相信数据7.1 用`cyclictest`摸底7.2 给你的程序施加压力7.3 利用`ftrace`追踪“大毛刺”的真凶8. 总结与展望【实时Linux核心技术:从概念到实战】06:编写你的第一个实时线程:API详解与注意事项我记得我第一次在Linux上写“实时”程序,是在一个六轴机械臂的控制柜里。老板拍着桌子说:“小张,这个关节插补周期必须稳定在2毫秒,少一微秒、多一微秒,机械臂就抖给你看!”我心想,这不简单吗,pthread_create搞个线程,再usleep(2000)不就完事了?结果现实狠狠给了我一巴掌。用示波器一量GPIO输出的波形,明明设的2ms,波形边缘却在1.8ms到2.5ms之间来回乱窜,偶尔还蹦出个几十毫秒的“大毛刺”。那台机械臂就像得了帕金森,抖得我后背发凉。后来我才明白,Linux的“实时”不是天上掉下来的馅饼,而是一个需要你小心翼翼去搭建的积木塔。一个看似无害的printf,一次疏忽的PTHREAD_INHERIT_SCHED默认值,甚至一个没被锁定在物理内存里的栈页面,都可能让你前功尽弃。说白了,在Linux上开发实时应用,系统的正确性不仅仅取决于“计算逻辑对不对”,更在于“能不能在物理世界规定的截止时间之前完成”。一个典型的电机FOC控制环,需要每50us采样一次相电流,在100us内就得算出新的PWM占空比。如果控制线程被调度器推后个几毫秒呢?轻则电机发出刺耳的尖啸,重则功率管直接炸给你看,甚至引发安全事故。Linux默认的调度策略(SCHED_OTHER)是给桌面和服务器设计的,它的核心哲学是“公平”和“高吞吐量”,它无法为我们的关键任务提供确定性的、硬性的时间保证。但好消息是,Linux内核从2.6版本开始,就完整地实现了POSIX 1003.1b实时扩展。通过一小撮精心设计的API调用,我们完全可以把普通的pthread变成一个具备高度确定性的实时线程。但怎么说呢,“简单”这个词有时是相对的。我见过太多工程师,照着网上的例子,把四个API依次调用一遍,编译运行,然后信心满满地觉得万事大吉。可一上压力测试就露馅了,原因往往是遗漏了某个看似不起眼的设置,或者踩进了一个隐蔽的陷阱里。这篇文章,我想带你从零开始,手把手地编写一个真正经得起考验的、周期性的实时线程。我们不搞虚的,会深入到:如何正确配置pthread的调度策略、优先级、继承方式,特别是那个坑了无数人的“继承”陷阱。如何用clock_nanosleep实现微秒级甚至更高精度的周期唤醒,并杜绝累积漂移。为什么你必须用mlockall把所有内存焊死在物理内存上,如何绑核,如何预热堆栈。我为你准备了一个完整、可编译、可测试的示例程序,可以直接拿去跑。最后,我会结合自己和朋友们的血泪史,聊聊线上环境中几个高频的“致命”错误和规避方法。读完这篇文章,你写出来的实时线程,将具备“稳定、低抖动”的基本素质。它也许还不能直接跟VxWorks叫板,但作为一个上层控制算法(比如插补、电机控制、数据采集)的可靠运行平台,是绝对够格了。1. 实时线程的“特权”本质:调度策略与优先级我们先从一个根本问题聊起:一个线程凭什么能“实时”?答案藏在Linux内核的调度器里。内核管理着所有想要在CPU上执行的任务(线程)。在现在这个CFS(完全公平调度器)大行其道的时代,实时调度策略是为数不多的、可以打破“公平”原则的“特权阶级”。它的逻辑不再是“大家轮流来”,而是赤裸裸的“优先级抢占”。我们来看一下你可以选择的三种调度策略,它们的区别就像三个不同级别的VIP通道:调度策略说明典型的实时优先级范围SCHED_OTHER默认的非实时分时策略,由CFS调度器管理。所有人公平地分一个CPU时间片。0(该策略下,nice值影响时间片权重,而不是这个实时优先级数值)SCHED_FIFO实时先进先出策略。一旦获得CPU,它会一直运行,直到被优先级更高的实时任务抢占、它自己主动让出CPU(比如睡了、阻塞了),或者运行完毕。没有时间片限制。1 ~ 99SCHED_RR实时轮转策略。基本同SCHED_FIFO,区别在于同一个优先级有好多个线程时,它们会按时间片轮流执行。有SCHED_FIFO任务时,就轮不到它们了。1 ~ 99对于我们今天要实现的周期实时任务来说,SCHED_FIFO就是那个不二之选。为什么?因为我们需要“确定性”——一旦定时器把我们唤醒,我们就应该立刻、马上投入运行,而不是被内核拖到“下一个公平的时间片”。SCHED_FIFO没有时间片的约束,可以最大程度地保证响应速度。还有一个新人常栽跟头的地方:Linux的实时优先级数值越大,代表的优先级越高。比如,优先级80的线程会无条件地抢占优先级40的线程。这一点跟某些RTOS(比如VxWorks)恰好相反,搞混了可是要出大事的。对了,想让一个普通用户态的进程拥有创建实时线程的“特权”,它得有相应的权限才行。通常需要进程具备CAP_SYS_NICE能力,或者更常见的是,调整RLIMIT_RTPRIO资源限制。很多发行版里,普通用户的ulimit -r(即RLIMIT_RTPRIO)硬限制是0,所以你大概率得用sudo来跑我们的测试程序,或者配置好相关权限。这个细节在生产环境部署时非常重要。2. Pthread属性配置:四步走,一步都不能少好了,原理弄明白了,我们来动手。创建一个实时线程,思路其实挺直观:先弄一个pthread_attr_t配置对象,把我们想要的“特权”都写进去,然后把这个配置对象传给pthread_create就行了。但,等等,我想想,多少人就是在这里栽了大跟头。感觉他们配置都写对了,但实际上这些属性被“悄悄忽略”了。我们得先把这个最致命的坑标出来,再说正确流程。2.1 第一步:初始化属性对象这步最简单,但很重要。你必须先初始化,不然那堆配置就是往一块没开垦的地里撒种子。#includepthread.h#includestdio.hpthread_attr_tattr;intret=pthread_attr_init(attr);if(ret!=0){// 记住!pthread_ 系列函数大多返回错误码,而不是设置 errnofprintf(stderr,"pthread_attr_init failed: %d\n",ret);}初始化之后,这个attr里面装的都是默认值,也就是“普通线程”的配置。我们接下来要做的,就是一项项把它改成我们想要的。2.2 第二步:设置调度策略使用pthread_attr_setschedpolicy,告诉系统:“我接下来创建的这个线程,想用SCHED_FIFO策略。”ret=pthread_attr_setschedpolicy(attr,SCHED_FIFO);if(ret!=0){fprintf(stderr,"pthread_attr_setschedpolicy failed: %d\n",ret);}走到这一步,attr对象里就记录了这个意愿。但是,注意我这个“但是”——这不代表pthread_create就一定会乖乖听话,后面会解释为啥。2.3 第三步:设置调度参数(优先级)既然选了VIP通道,那总得有个VIP等级吧。我们用struct sched_param来设置这个等级。这个结构体里,对我们有用的,就只有一个成员sched_priority。#includestring.hstructsched_paramparam;memset(param,0,sizeof(param));// 好习惯,清零param.sched_priority=80;// 设置实时优先级为 80ret=pthread_attr_setschedparam(attr,param);if(ret!=0){fprintf(stderr,"pthread_attr_setschedparam failed: %d\n",ret);}把优先级设成80,算是相当高了。但我劝你别一上来就设成99。内核里有很多关键的内核线程(比如负责CPU负载均衡的迁移线程、处理硬件中断的软中断内核线程)也运行在高优先级上。你把用户态线程设成99,一跑起来可能直接把系统搞“假死”了,连ssh都连不进去。通常,50到85之间是个比较安全且有效的范围,也方便给以后可能需要的更高优先级任务留出空间。2.4 最关键的一步:设置继承策略,PTHREAD_EXPLICIT_SCHED这是全篇最要命,也最容易被人忽视的一个配置。在pthread_attr_t的默认设置里,有一个叫inheritsched的字段,它的默认值是PTHREAD_INHERIT_SCHED。这个值的意思翻译过来就是:“喂,pthread_create,你创建新线程的时候,别用我attr里写的调度策略和优先级啊,直接去抄创建者它自己的就好啦!”这下你明白了吧?假设你的main函数所在的主线程,它是一个普普通通的SCHED_OTHER线程。那么,就算你在前面几节,辛辛苦苦地把attr的SCHED_FIFO和80优先级都设好了,pthread_create这家伙也会对你视而不见,跑去抄主线程的“普通”身份。你满怀期待地创建了一个以为是VIP的线程,结果人家拿的还是普通观众的票。你的所有属性设置,都静默失败了,而且没有任何API返回错误给你看。这,就是我见过最多的“为什么我的实时线程不实时?”的原因。所以,解决办法就是,你得揪着pthread_create的耳朵,明明白白地告诉它:“别自作主张到处乱抄,就用我给你的值!”下面这行代码,就是你跟它的对话:ret=pthread_attr_setinheritsched(attr,PTHREAD_EXPLICIT_SCHED);if(ret!=0){fprintf(stderr,"pthread_attr_setinheritsched failed: %d\n",ret);}只有加了这一行,前面的SCHED_FIFO和优先级80的设置,才算真正意义上激活了。从设计哲学上讲,PTHREAD_INHERIT_SCHED这个默认值设计得挺有道理,它保证了系统整体的安全性,防止不懂的人瞎配置搞出问题。但正是这种“安全”的设计,成了一个等着我们这些懂行的开发者往里跳的陷阱。2.5 验证配置:眼见为实安全起见,在pthread_create之前,我们最好还是把attr对象里的配置读出来看一眼,确认一下我们的“思想”已经“写入”了对象。这就相当于出发前看一眼油箱有没有加满。intpolicy;structsched_paramp;pthread_attr_getschedpolicy(attr,policy);pthread_attr_getschedparam(attr,p);intinherit;pthread_attr_getinheritsched(attr,inherit);printf("配置验证 - 策略: %d (SCHED_FIFO=%d), 优先级: %d, 继承模式: %s\n",policy,SCHED_FIFO,p.sched_priority,(inherit==PTHREAD_EXPLICIT_SCHED)?"EXPLICIT":"INHERIT");这个小小的防御性步骤,能替我们省去未来无数个抓破头皮的debug通宵。3. 周期的节拍器:clock_nanosleep与精确唤醒调度策略和优先级搞定了,线程就具备了“一声令下立刻冲刺”的能力。但下一个关键问题是:“我们该在什么时间点发出起跑指令?”对于一个周期任务,我们需要一个精确的“节拍器”,它能每隔T毫秒就精准地唤醒我们一次。3.1sleep()和nanosleep()为什么不行?直觉上,我们可能会用sleep()或nanosleep()。但很遗憾,它们俩不够格。sleep()的精度是秒级的,这对于我们动辄微秒级的周期来说,就像用日晷来测百米冲刺,根本没法用。nanosleep()呢?好一点,它支持纳秒级精度。但问题是,它还是一个相对时间的休眠接口。什么意思?你告诉它:“从现在开始,再睡2ms”。然后线程被调度回来,到开始执行用户代码,这里头有个调度延迟。假设调度延迟是10us,那你第一个周期实际执行的时间点,就成了t = 2ms + 10us。下一个周期,你又从“现在”这个已经延迟了的时间点再往后睡2ms,如此循环往复。用不了多久,你的任务时间基准就会像一块廉价手表一样,越来越“慢”,产生不可接受的累积漂移。这在需要跟外部设备保持严格时间同步的控制系统里,是绝对不允许的。nanosleep本身基于高精度定时器(hrtimer),精度是够的,但它缺少了一个关键能力:无法锚定一个“绝对时间点”。3.2clock_nanosleep的使用诀窍clock_nanosleep是解决这个问题的利刃。它是POSIX标准提供的高精度睡眠接口,比nanosleep多了几个关键参数,功能强了一大截。intclock_nanosleep(clockid_tclock_id,intflags,conststructtimespec*rqtp,structtimespec*rmtp);这里有两个参数,我们必须得吃透:clock_id:指定参考时钟。对于我们实时任务,必须、一定、只能用CLOCK_MONOTONIC,离那个CLOCK_REALTIME远一点。CLOCK_REALTIME是啥?就是我们平时用date命令看到那个时间,它可能被系统管理员随意调整,也可能被NTP网络校时服务悄悄“顺滑”个几毫秒。如果它在你睡眠时往前跳了几十分钟,你的线程可能要多睡几十分钟;往后跳了呢?你可能立刻醒来,导致周期紊乱。而CLOCK_MONOTONIC是单调递增的,从系统启动开始滴答,永远向前,不受任何外界干预。这才是我们需要的稳定时钟源。flags:如果设为0,就是普通的相对睡眠,跟nanosleep类似。如果设为TIMER_ABSTIME,那意义就完全变了——rqtp不再是一个时长,而是一个绝对时间点。线程会一直沉睡,直到系统时钟clock

相关新闻

AI产品测试验收:四维框架与工程实践

AI产品测试验收:四维框架与工程实践

1. AI时代产品经理的测试验收新范式当Stable Diffusion能根据自然语言生成高清图像、ChatGPT可以理解模糊需求输出代码时,传统软件测试的边界正在被重构。作为经历过三次技术浪潮的老兵,我亲眼见证测试工程师的职责从"找按钮点击不了"的BUG&am…

2026/8/9 22:40:26 阅读更多 →
抖音无水印下载器:3步搞定高清视频批量下载的终极工具

抖音无水印下载器:3步搞定高清视频批量下载的终极工具

抖音无水印下载器:3步搞定高清视频批量下载的终极工具 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback suppo…

2026/8/9 22:40:26 阅读更多 →
5分钟快速上手:免费开启《命运2》单人模式,告别强制匹配烦恼

5分钟快速上手:免费开启《命运2》单人模式,告别强制匹配烦恼

5分钟快速上手:免费开启《命运2》单人模式,告别强制匹配烦恼 【免费下载链接】Destiny-2-Solo-Enabler Repo containing the C# and XAML code for the D2SE program. Included is also the dependency for the program, and image asset. 项目地址: h…

2026/8/9 22:40:26 阅读更多 →

最新新闻

二进制遗传算法在电力系统经济调度中的应用与实现

二进制遗传算法在电力系统经济调度中的应用与实现

1. 电力系统经济调度问题的背景与挑战电力系统经济调度(Economic Dispatch, ED)是电力系统运行中的核心优化问题之一。简单来说,就是在满足各种约束条件的前提下,如何分配各发电机组的出力,使得总发电成本最低。这个问…

2026/8/10 6:44:20 阅读更多 →
C++实战项目构建指南:从技术选型到简历亮点的全流程解析

C++实战项目构建指南:从技术选型到简历亮点的全流程解析

1. 为什么你的C项目简历总被刷?先想清楚“实战”到底指什么很多同学在准备校招简历时,都会去找“C实战项目”,但往往陷入一个误区:把“能跑通”等同于“有含金量”。结果就是,简历上列了一堆项目,面试官一问…

2026/8/10 6:44:20 阅读更多 →
校园水站配送管理系统开发实战:Vue3与Python技术栈解析

校园水站配送管理系统开发实战:Vue3与Python技术栈解析

1. 项目背景与需求分析学校水站配送管理系统是一个典型的校园服务类信息化解决方案。在高校环境中,桶装水配送涉及学生宿舍、教学楼、办公楼等多个场景,传统的人工记录和电话预约方式存在效率低下、易出错、难以统计等痛点。这个系统需要解决的核心问题包…

2026/8/10 6:44:20 阅读更多 →
Linux find命令高效数据处理实战指南

Linux find命令高效数据处理实战指南

1. Linux find命令高效数据处理操作指南作为一名Linux系统管理员,我每天都要处理海量数据文件。find命令就像我的瑞士军刀,15年来帮我解决了无数文件查找与批量处理难题。今天分享的不仅是基础用法,更是实战中总结的高效数据处理套路&#xf…

2026/8/10 6:44:20 阅读更多 →
大型FPS多人游戏架构:权威服务器、状态同步与性能优化实战

大型FPS多人游戏架构:权威服务器、状态同步与性能优化实战

1. 项目概述:从“大战场”到“高并发”的挑战当“Ultimate Warfare”这样的标题出现在眼前时,我脑海里浮现的不仅仅是枪林弹雨的战场画面,更是一系列复杂的技术难题堆砌成的“高墙”。一个大型FPS多人战争游戏,其核心挑战早已超越…

2026/8/10 6:44:20 阅读更多 →
微信小程序外卖商城全栈开发:从源码解析到部署上线的实践指南

微信小程序外卖商城全栈开发:从源码解析到部署上线的实践指南

在实际项目中,一个功能完整、可直接部署的微信小程序外卖商城源码是快速启动业务、验证模式或学习全栈开发流程的宝贵资源。这类项目通常涉及前端小程序界面、后端业务逻辑、数据库设计以及微信生态的深度集成,如登录、支付、地图、消息订阅等。对于开发…

2026/8/10 6:43:20 阅读更多 →

日新闻

GraphQL-CSS API全解析:useGqlCSS、GqlCSS组件与getStyles实用指南

GraphQL-CSS API全解析:useGqlCSS、GqlCSS组件与getStyles实用指南

GraphQL-CSS API全解析:useGqlCSS、GqlCSS组件与getStyles实用指南 【免费下载链接】graphql-css A blazing fast CSS-in-GQL™ library. 项目地址: https://gitcode.com/gh_mirrors/gr/graphql-css GraphQL-CSS是一个基于GraphQL的CSS-in-GQL™库&#xff0…

2026/8/10 0:00:02 阅读更多 →
告别语言障碍:KISS Translator 双语翻译插件终极指南

告别语言障碍:KISS Translator 双语翻译插件终极指南

告别语言障碍:KISS Translator 双语翻译插件终极指南 【免费下载链接】kiss-translator A simple, open source bilingual translation extension & Greasemonkey script (一个简约、开源的 双语对照翻译扩展 & 油猴脚本) 项目地址: https://gitcode.com/…

2026/8/10 0:00:02 阅读更多 →
BepInEx配置管理器:游戏插件配置的终极可视化解决方案

BepInEx配置管理器:游戏插件配置的终极可视化解决方案

BepInEx配置管理器:游戏插件配置的终极可视化解决方案 【免费下载链接】BepInEx.ConfigurationManager Plugin configuration manager for BepInEx 项目地址: https://gitcode.com/gh_mirrors/be/BepInEx.ConfigurationManager 你是否曾经因为游戏插件的复杂…

2026/8/10 0:00:02 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/10 1:05:29 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/10 1:05:29 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/10 1:05:29 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/9 17:05:02 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/10 1:05:29 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/9 17:05:02 阅读更多 →