鸿蒙轻内核M核源码分析:数据结构之任务排序链表

摘要:鸿蒙轻内核的任务排序链表,用于任务延迟到期/超时唤醒等业务场景,是一个非常重要、非常基础的数据结构。

本文会继续给读者介绍鸿蒙轻内核源码中重要的数据结构:任务排序链表TaskSortLinkAttr。鸿蒙轻内核的任务排序链表,用于任务延迟到期/超时唤醒等业务场景,是一个非常重要、非常基础的数据结构。本文中所涉及的源码,以OpenHarmony LiteOS-M内核为例,均可以在开源站点https://gitee.com/openharmony/kernel_liteos_m 获取。

1 任务排序链表

我们先看下任务排序链接的数据结构。任务排序链表是一个环状的双向链表数组,任务排序链表属性结构体TaskSortLinkAttr作为双向链表的头结点,指向双向链表数组的第一个元素,还维护游标信息,记录当前的位置信息。我们先看下排序链表属性的结构体的定义。

1.1 任务排序链表属性结构体定义

在kernel\include\los_task.h头文件中定义了排序链表属性的结构体TaskSortLinkAttr。该结构体定义了排序链表的头节点LOS_DL_LIST *sortLink,游标UINT16 cursor,还有一个保留字段,暂时没有使用。

源码如下:

   typedef struct {
        LOS_DL_LIST *sortLink;
        UINT16      cursor;
        UINT16      reserved;
    } TaskSortLinkAttr;

在文件kernel\src\los_task.c中定义了排序链表属性结构体TaskSortLinkAttr类型的全局变量g_taskSortLink,该全局变量的成员变量sortLink作为排序链表的头结点,指向一个长度为32的环状的双向链表数组,成员变量cursor作为游标记录环状数组的当前游标位置。源代码如下。

​​​​​​​    LITE_OS_SEC_BSS  TaskSortLinkAttr                    g_taskSortLink;

我们使用示意图来讲述一下。任务排序链表是环状双向链表数组,长度为32,每一个元素是一个双向链表,挂载任务LosTaskCB的链表节点timerList。任务LosTaskCB的成员变量idxRollNum记录数组的索引和滚动数。全局变量g_taskSortLink的成员变量cursor记录当前游标位置,每过一个Tick,游标指向下一个位置,转一轮需要32 ticks。当运行到的数组位置,双向链表不为空,则把第一个节点维护的滚动数减1。这样的数据结构类似钟表表盘,也称为时间轮。

我们举个例子来说明,基于时间轮实现的任务排序链表是如何管理任务延迟超时的。假如当前游标cursor为1,当一个任务需要延时72 ticks,72=2*32+8,表示排序索引sortIndex为8,滚动数rollNum为2。会把任务插入数组索引为sortIndex+cursor=9的双向链表位置,索要9处的双向链表维护节点的滚动为2。随着Tick时间的进行,从当前游标位置运行到数组索引位置9,历时8 ticks。运行到9时,如果滚动数大于0,则把滚动数减1。等再运行2轮,共需要72 ticks,任务就会延迟到期,可以从排序链表移除。每个数组元素对应的双向链表的第一个链表节点的滚动数表示需要转多少轮,节点任务才到期。第二个链表节点的滚动数需要加上第一个节点的滚动数,表示第二个节点需要转的轮数。依次类推。

示意图如下:

1.2 任务排序链表宏定义

在OS_TSK_SORTLINK_LEN头文件中定义了一些和任务排序链表相关的宏定义。延迟任务双向链表数组的长度定义为32,高阶bit位位数为5,低阶bit位位数为27。对于任务的超时时间,取其高27位作为滚动数,低5位作为数组索引。

源码如下:

​​​​​​​        /**
        * 延迟任务双向链表数组的数量(桶的数量):32
        */
        #define OS_TSK_SORTLINK_LEN                         32
     
        /**
        * 高阶bit位数目:5
        */
        #define OS_TSK_HIGH_BITS                            5U
     
        /**
        * 低阶bit位数目:27
        */
        #define OS_TSK_LOW_BITS                             (32U - OS_TSK_HIGH_BITS)
     
        /**
        * 滚动数最大值:0xFFFF FFDF,1111 0111 1111 1111 1111 1111 1101 1111
        */
        #define OS_TSK_MAX_ROLLNUM                          (0xFFFFFFFFU - OS_TSK_SORTLINK_LEN)
     
        /**
        * 任务延迟时间数的位宽:5
        */
        #define OS_TSK_SORTLINK_LOGLEN                      5
     
        /**
        * 延迟任务的桶编号的掩码:31、0001 1111
        */
        #define OS_TSK_SORTLINK_MASK                        (OS_TSK_SORTLINK_LEN - 1U)
     
        /**
        * 滚动数的高阶掩码:1111 1000 0000 0000 0000 0000 0000 0000
        */
        #define OS_TSK_HIGH_BITS_MASK                       (OS_TSK_SORTLINK_MASK << OS_TSK_LOW_BITS)
     
        /**
        * 滚动数的低阶掩码:0000 0111 1111 1111 1111 1111 1111 1111
        */
        #define OS_TSK_LOW_BITS_MASK                        (~OS_TSK_HIGH_BITS_MASK)
     

2 任务排序链表操作

我们分析下任务排序链表的操作,包含初始化,插入,删除,滚动数更新,获取下一个到期时间等。

2.1 初始化排序链表

在系系统内核初始化启动阶段,在函数UINT32 OsTaskInit(VOID)中初始化任务排序链表。该函数的调用关系如下,main.c:main() --> kernel\src\los_init.c:LOS_KernelInit() --> kernel\src\los_task.c:OsTaskInit()。

初始化排序链表函数的源码如下:

​​​​​​​    LITE_OS_SEC_TEXT_INIT UINT32 OsTaskInit(VOID)
    {
        UINT32 size;
        UINT32 index;
        LOS_DL_LIST *listObject = NULL;
        ......
    ⑴  size = sizeof(LOS_DL_LIST) * OS_TSK_SORTLINK_LEN;
        listObject = (LOS_DL_LIST *)LOS_MemAlloc(m_aucSysMem0, size);
    ⑵  if (listObject == NULL) {
            (VOID)LOS_MemFree(m_aucSysMem0, g_taskCBArray);
            return LOS_ERRNO_TSK_NO_MEMORY;
        }
     
    ⑶  (VOID)memset_s((VOID *)listObject, size, 0, size);
    ⑷  g_taskSortLink.sortLink = listObject;
        g_taskSortLink.cursor = 0;
        for (index = 0; index < OS_TSK_SORTLINK_LEN; index++, listObject++) {
    ⑸      LOS_ListInit(listObject);
        }
     
        return LOS_OK;
    }
     

⑴处代码计算需要申请的双向链表的内存大小,OS_TSK_SORTLINK_LEN为32,即需要为32个双向链表节点申请内存空间。然后申请内存,⑵处申请内存失败时返回相应错误码。⑶处初始化申请的内存区域为0等。⑷处把申请的双向链表节点赋值给g_taskSortLink的链表节点.sortLink,作为排序链表的头节点,游标.cursor初始化为0。然后⑸处的循环,调用LOS_ListInit()函数把双向链表数组每个元素都初始化为双向循环链表。

2.2 插入排序链表

插入排序链表的函数为OsTaskAdd2TimerList()。在任务等待互斥锁/信号量等资源时,都需要调用该函数将任务加入到对应的排序链表中。该函数包含两个入参,第一个参数LosTaskCB *taskCB用于指定要延迟的任务,第二个参数UINT32 timeout指定超时等待时间。

源码如下:

​​​​​​​    LITE_OS_SEC_TEXT VOID OsTaskAdd2TimerList(LosTaskCB *taskCB, UINT32 timeout)
    {
        LosTaskCB *taskDelay = NULL;
        LOS_DL_LIST *listObject = NULL;
        UINT32 sortIndex;
        UINT32 rollNum;
     
    ⑴  sortIndex = timeout & OS_TSK_SORTLINK_MASK;
        rollNum = (timeout >> OS_TSK_SORTLINK_LOGLEN);
    ⑵  (sortIndex > 0) ? 0 : (rollNum--);
    ⑶  EVALUATE_L(taskCB->idxRollNum, rollNum);
    ⑷  sortIndex = (sortIndex + g_taskSortLink.cursor);
        sortIndex = sortIndex & OS_TSK_SORTLINK_MASK;
    ⑸  EVALUATE_H(taskCB->idxRollNum, sortIndex);
    ⑹  listObject = g_taskSortLink.sortLink + sortIndex;
    ⑺  if (listObject->pstNext == listObject) {
            LOS_ListTailInsert(listObject, &taskCB->timerList);
        } else {
    ⑻      taskDelay = LOS_DL_LIST_ENTRY((listObject)->pstNext, LosTaskCB, timerList);
            do {
    ⑼          if (UWROLLNUM(taskDelay->idxRollNum) <= UWROLLNUM(taskCB->idxRollNum)) {
                    UWROLLNUMSUB(taskCB->idxRollNum, taskDelay->idxRollNum);
                } else {
    ⑽              UWROLLNUMSUB(taskDelay->idxRollNum, taskCB->idxRollNum);
                    break;
                }
     
    ⑾          taskDelay = LOS_DL_LIST_ENTRY(taskDelay->timerList.pstNext, LosTaskCB, timerList);
            } while (&taskDelay->timerList != (listObject));
     
    ⑿      LOS_ListTailInsert(&taskDelay->timerList, &taskCB->timerList);
        }
    }
     

⑴处代码计算等待时间timeout的低5位作为数组索引,高27位作为滚动数rollNum。这2行代码数学上的意义,就是把等待时间处于32得到的商作为滚动数,余数作为数组索引。⑵处代码,如果余数为0,可以整除时,滚动数减1。减1设计的原因是,在函数VOID OsTaskScan(VOID)中,每一个tick到来时,如果滚动数大于0,滚动数减1,并继续滚动一圈。后文会分析该函数VOID OsTaskScan(VOID)。

⑶处代码把滚动数赋值给任务taskCB->idxRollNum的低27位。⑷处把数组索引加上游标,然后执行⑸赋值给任务taskCB->idxRollNum的高5位。⑹根据数组索引获取双向链表头结点,⑺如果此处双向链表为空,直接插入链表里。如果链表不为空,执行⑻获取第一个链表节点对应的任务taskDelay,然后遍历循环双向链表,把任务插入到合适的位置。⑼处如果待插入任务taskCB的滚动数大于等于当前链表节点对应任务的滚动数,则从待插入任务taskCB的滚动数中减去当前链表节点对应任务的滚动数,然后执行⑾获取下一个节点继续遍历。⑽处如果待插入任务taskCB的滚动数小于当前链表节点对应任务的滚动数,则从当前链表节点对应任务的滚动数中减去待插入任务taskCB的滚动数,然后跳出循环。执行⑿,完成任务插入。插入过程,可以结合上文的示意图进行理解。

2.3 从排序链表中删除

从排序链表中删除的函数为VOID OsTimerListDelete(LosTaskCB *taskCB)。在任务恢复/删除等场景中,需要调用该函数将任务从任务排序链表中删除。该函数包含一个参数LosTaskCB *taskCB,用于指定要从排序链表中删除的任务。

源码如下:

​​​​​​​    LITE_OS_SEC_TEXT VOID OsTimerListDelete(LosTaskCB *taskCB)
    {
        LOS_DL_LIST  *listObject = NULL;
        LosTaskCB  *nextTask = NULL;
        UINT32 sortIndex;
     
    ⑴  sortIndex = UWSORTINDEX(taskCB->idxRollNum);
    ⑵  listObject = g_taskSortLink.sortLink + sortIndex;
     
    ⑶  if (listObject != taskCB->timerList.pstNext) {
    ⑷      nextTask = LOS_DL_LIST_ENTRY(taskCB->timerList.pstNext, LosTaskCB, timerList);
            UWROLLNUMADD(nextTask->idxRollNum, taskCB->idxRollNum);
        }
     
    ⑸  LOS_ListDelete(&taskCB->timerList);
    }

⑴处代码获取待从排序链表中删除的任务对应的数字索引。⑵处代码获取排序链表的头节点listObject。⑶处代码判断待删除节点是否是最后一个节点,如果不是最后一个节点,执行执行⑷处代码获取待删除节点的下一个节点对应的任务nextTask,在下一个节点的滚动数中增加待删除节点的滚动数,然后执行⑸处代码执行删除操作。如果是最后一个节点,直接执行⑸处代码删除该节点即可。

2.4 获取下一个超时到期时间

获取下一个超时到期时间的函数为OsTaskNextSwitchTimeGet(),我们分析下其代码。

源码如下:

​​​​​​​    UINT32 OsTaskNextSwitchTimeGet(VOID)
    {
        LosTaskCB *taskCB = NULL;
        UINT32 taskSortLinkTick = LOS_WAIT_FOREVER;
        LOS_DL_LIST *listObject = NULL;
        UINT32 tempTicks;
        UINT32 index;
     
    ⑴  for (index = 0; index < OS_TSK_SORTLINK_LEN; index++) {
    ⑵      listObject = g_taskSortLink.sortLink + ((g_taskSortLink.cursor + index) % OS_TSK_SORTLINK_LEN);
    ⑶      if (!LOS_ListEmpty(listObject)) {
    ⑷          taskCB = LOS_DL_LIST_ENTRY((listObject)->pstNext, LosTaskCB, timerList);
    ⑸          tempTicks = (index == 0) ? OS_TSK_SORTLINK_LEN : index;
    ⑹          tempTicks += (UINT32)(UWROLLNUM((UINT32)taskCB->idxRollNum) * OS_TSK_SORTLINK_LEN);
    ⑺          if (taskSortLinkTick > tempTicks) {
                    taskSortLinkTick = tempTicks;
                }
            }
        }
        return taskSortLinkTick;
    }

⑴处代码循环遍历双向链表数组,⑵处代码从当前游标位置开始获取排序链表的头节点listObject。⑶处代码判断排序链表是否为空,如果排序链表为空,则继续遍历下一个数组。如果链表不为空,⑷处代码获取排序链表的第一个链表节点对应的任务。⑸处如果遍历的数字索引为0,tick数目使用32,否则使用具体的数字索引。⑹处获取任务的滚动数,计算出需要的等待时间,加上⑸处计算出的不足滚动一圈的时间。⑺处计算出需要等待的最小时间,即下一个最快到期的时间。

3 排序链表和Tick时间的关系

任务加入到排序链表后,时间一个tick一个tick的逝去,排序链表中的滚动数该如何更新呢?

时间每走过一个tick,系统就会调用Tick中断的处理函数OsTickHandler(),该函数在kernel\src\los_tick.c文件中实现。下面是该函数的代码片段,⑴处代码分别任务的超时到期情况。

​​​​​​​    LITE_OS_SEC_TEXT VOID OsTickHandler(VOID)
    {
    #if (LOSCFG_BASE_CORE_TICK_HW_TIME == 1)
        platform_tick_handler();
    #endif
     
        g_ullTickCount++;
     
    #if (LOSCFG_BASE_CORE_TIMESLICE == 1)
        OsTimesliceCheck();
    #endif
     
    ⑴  OsTaskScan();  // task timeout scan
     
    #if (LOSCFG_BASE_CORE_SWTMR == 1)
        (VOID)OsSwtmrScan();
    #endif
    }

详细分析下函数OsTaskScan(),来了解排序链表和tick时间的关系。函数在kernel\base\los_task.c文件中实现,代码片段如下:

​​​​​​​    LITE_OS_SEC_TEXT VOID OsTaskScan(VOID)
    {
        LosTaskCB *taskCB = NULL;
        BOOL needSchedule = FALSE;
        LOS_DL_LIST *listObject = NULL;
        UINT16 tempStatus;
        UINTPTR intSave;
        intSave = LOS_IntLock();
     
    ⑴  g_taskSortLink.cursor = (g_taskSortLink.cursor + 1) % OS_TSK_SORTLINK_LEN;
        listObject = g_taskSortLink.sortLink + g_taskSortLink.cursor;
    ⑵  if (listObject->pstNext == listObject) {
            LOS_IntRestore(intSave);
            return;
        }
     
    ⑶  for (taskCB = LOS_DL_LIST_ENTRY((listObject)->pstNext, LosTaskCB, timerList);
             &taskCB->timerList != (listObject);) {
            tempStatus = taskCB->taskStatus;
    ⑷      if (UWROLLNUM(taskCB->idxRollNum) > 0) {
                UWROLLNUMDEC(taskCB->idxRollNum);
                break;
            }
     
    ⑸      LOS_ListDelete(&taskCB->timerList);
    ⑹      if (tempStatus & OS_TASK_STATUS_PEND) {
                taskCB->taskStatus &= ~(OS_TASK_STATUS_PEND);
                LOS_ListDelete(&taskCB->pendList);
                taskCB->taskSem = NULL;
                taskCB->taskMux = NULL;
            }
    ⑺      else if (tempStatus & OS_TASK_STATUS_EVENT) {
                taskCB->taskStatus &= ~(OS_TASK_STATUS_EVENT);
            }
    ⑻      else if (tempStatus & OS_TASK_STATUS_PEND_QUEUE) {
                LOS_ListDelete(&taskCB->pendList);
                taskCB->taskStatus &= ~(OS_TASK_STATUS_PEND_QUEUE);
            } else {
                taskCB->taskStatus &= ~(OS_TASK_STATUS_DELAY);
            }
     
    ⑼      if (!(tempStatus & OS_TASK_STATUS_SUSPEND)) {
                taskCB->taskStatus |= OS_TASK_STATUS_READY;
                OsHookCall(LOS_HOOK_TYPE_MOVEDTASKTOREADYSTATE, taskCB);
                OsPriqueueEnqueue(&taskCB->pendList, taskCB->priority);
                needSchedule = TRUE;
            }
     
            if (listObject->pstNext == listObject) {
                break;
            }
     
            taskCB = LOS_DL_LIST_ENTRY(listObject->pstNext, LosTaskCB, timerList);
        }
     
        LOS_IntRestore(intSave);
     
    ⑽  if (needSchedule) {
            LOS_Schedule();
        }
    }

⑴处代码更新全局变量g_taskSortLink的游标,指向双向链表数组下一个位置,然后获取该位置的双向链表头结点listObject。⑵如果链表为空,则返回。如果双向链表不为空,则执行⑶循环遍历每一个链表节点。⑷处如果链表节点的滚动数大于0,则滚动数减1,说明任务还需要继续等待一轮。如果链表节点的滚动数等于0,说明任务超时到期,执行⑸从排序链表中删除。接下来需要根据任务状态分别处理,⑹处如果代码是阻塞状态,取消阻塞状态,并从阻塞链表中删除。⑺处如果任务阻塞在事件中,取消阻塞状态。⑻如果任务阻塞在队列,从阻塞链表中删除,取消阻塞状态,如果不是上述状态,取消延迟状态OS_TASK_STATUS_DELAY。⑼处如果代码是挂起状态,设置任务为就绪状态,加入任务就绪队列,设置需要重新调度标记。⑽如果设置需要重新调度,调用调度函数触发任务调度。

小结

掌握鸿蒙轻内核的排序链表TaskSortLinkAttr这一重要的数据结构,会给进一步学习、分析鸿蒙轻内核源代码打下了基础,让后续的学习更加容易。后续也会陆续推出更多的分享文章,敬请期待,也欢迎大家分享学习、使用鸿蒙轻内核的心得,有任何问题、建议,都可以留言给我们: https://gitee.com/openharmony/kernel_liteos_m/issues 。为了更容易找到鸿蒙轻内核代码仓,建议访问 https://gitee.com/openharmony/kernel_liteos_m ,关注Watch、点赞Star、并Fork到自己账户下,谢谢。

 

点击关注,第一时间了解华为云新鲜技术~

相关推荐

鸿蒙案例上新啦 | 购物、听歌、健身:15个模板带你一键激活社交娱乐

页面层级如何组织、跨页共享状态如何同步、列表与详情及个人中心如何形成稳定闭环。鸿蒙开发实践中心将这些高频消费与互动场景沉淀为可参考的标准模板,提供从业务架构到界面实现的快捷实践入口。更多实战案例欢迎前往鸿蒙开发实践中心案例中心查看并开启云端体验。

华为云官方博客 338

鸿蒙案例上新啦 | 出门打车、到家上课:25个模板带你一屏打通日常生活

如何合理拆分页面组件、如何建立单一可信的状态源、如何让用户在每一步操作中都获得明确反馈。鸿蒙开发实践中心以标准化的应用与元服务模板为入口,将清晰的业务架构与可复用的代码结构直观呈现。不妨立即挑选一个感兴趣的方向进入云端环境,从页面布局、组件封装、状态管理到路由组织,亲手跑通你的鸿蒙实战项目。

华为云官方博客 325

LakeAgent:DWS数据仓库的第二大脑,告别 “翻译式运维”,迈入智能自治时代

和普通 SQL 改写工具不同,LakeAgent 自动做多方案代价对比,主动规避负优化陷阱:补充分区键过滤实现剪枝,扫描分区由 37 收敛至 1,执行代价从 758.28 降至 113.74;未来的数据仓库,将不止能算、能存,更能看懂自己、诊断自己、理解自己。长久以来,数仓的智能都依附于人:信号需要人解读,瓶颈需要人研判,经验困在个体里,无法随底座永续生长。CPU 高、CPU 告警、CPU 诊断、CPU 使用率过高、CPU 满。语法、错误码、计费、性能调优、最佳实践、故障处置等全场景内容。

华为云官方博客 555

如何使用RDS Supabase后端BaaS能力:文件存储(File Storage)

• product-images(公开桶,允许公共读取):策略名称"Public read for product-images",允许SELECT,目标角色anon,策略定义bucket_id = 'product-images'。上传/删除需另配INSERT/DELETE策略,详见SQL。• product-specs(私有桶,仅认证用户访问自己的文件夹):建议拆为上传、读取、删除三条策略,策略定义均为 bucket_id = 'product-specs' 且仅限本人文件夹(详见下文 SQL)。

华为云官方博客 476

如何使用RDS Supabase后端BaaS能力:实时订阅与推送(Realtime)

Realtime 把数据库的每次变更同步到客户端:表里增、删、改一行,订阅者无需刷新页面或主动请求即可秒级收到。三大能力各司其职:• Postgres Changes — 监听表的 INSERT/UPDATE/DELETE,变化即通知• Broadcast — 客户端之间直接互发,适合瞬时通知、协同编辑• Presence — 跟踪频道里“谁在线”典型场景有实时数据展示(订单、库存、监控指标即时刷新)、即时通讯(消息收发、在线名单、“对方正在输入”)、协同编辑与实时通知。

华为云官方博客 465

AI Agent如何通过MCP连接到华为云RDS Supabase应用平台

Schema元数据列出所有可访问的表(按schema分组)。Schema元数据列出表的列及元数据(类型/默认值/约束)。Schema元数据列出所有约束(PK/FK/UNIQUE/CHECK/EXCLUDE)。可按schema/表/类型过滤。Schema元数据列出所有外键关系。可按schema/表过滤。Schema元数据列出所有索引及定义和大小。可按schema/表过滤。Schema元数据列出已应用的数据库迁移记录。Schema元数据列出已安装的PostgreSQL扩展。

华为云官方博客 473

华为大数据Flink让每一 CU 算力,跑出开源 5.74 倍的性能

1. 开源Apache Flink 已成为业界流计算事实标准,但在极端重负载场景下存在性能瓶颈。2. 华为大数据Flink通过多项自研深度优化,在执行计划、算子执行、状态存储三个层面构建协同的优化体系。3. Nexmark Benchmark 测试结果:整体性能提升 5.74 倍,极端重负载场景性能领先最高 18.3 倍。4. 100% 兼容 Apache Flink 1.20,业务代码零改造,无缝迁移。

华为云官方博客 380

LakeAgent实战 | 业务分析篇从一句提问到业务分析

本文以“订单金额变化”分析为例,展示LakeAgent如何通过自然语言提问,结合DataArtsStudio的数据资产与专业技能,帮助业务人员快速定位数据、生成SQL、追踪血缘、生成报告。从问题出发,逐步实现数据发现、变化洞察、原因追溯与团队协作,最终形成可复用的分析流程与企业规则,显著提升数据分析效率与一致性。

华为云官方博客 389

华为云RDS Supabase AI应用已开放公测 :30分钟搭建AI应用后端

认证、存储、实时推送、数据库API——4个后端模块,传统开发需要数周。今天,你只需要30分钟。AI创业公司的全栈开发工程师。上周老板说"下周要上线的AI对话应用,后端你来搞"——认证鉴权、数据库接口、文件存储、实时推送,每一个模块都需要数周搭建,而市场不会等你。小张打开华为云RDS Supabase,30分钟搭好认证、数据库API、对象存储,剩下的时间全用来打磨AI交互体验。基于开源Supabase+华为云RDS PostgreSQL全托管能力,为开发者提供。

华为云官方博客 396

如何使用RDS Supabase后端BaaS能力:数据库函数(Database Function)

上一篇介绍了 Database Data API——建表即自动生成增删改查接口,解决单表读写,但聚合统计、跨表事务、字段自动维护等逻辑已超出其能力边界。本篇推进到数据库函数(Database Function):把业务逻辑封装进数据库,前端通过 .rpc() 调用,由触发器自动响应数据变更。上一篇中,小张基于 Data API 完成了产品目录的建表与基础读写。但新需求随之而来:按分类统计产品数与价格区间、上架新品同时写产品表与定价表、产品修改后自动刷新更新时间。

华为云官方博客 464

如何使用RDS Supabase后端BaaS能力:创表即生成API(Database Data API)

认证、存储、实时推送、数据库API——4个后端模块,传统开发要数周。本系列逐个拆解,首篇聚焦数据库API(Database Data API):建表即得 API,无需手写后端。小张,AI创业公司的全栈工程师。老板让他做个产品目录页,展示产品与价格、支持上下架。传统做法要搭后端、写接口、配权限,工期少说1-2周;而在华为云RDS Supabase,建两张表、应用 SDK 直连,几分钟增删改查全跑通。

华为云官方博客 478

从一句话到一个能出去的链接,AI开发者空间做了什么

自行搭建的 Agent、正在使用的开源项目、团队既有的工具,都可以接入,可以通过AI创建或者手动搭建环境;华为云 AI开发者空间——面向开发者的云端一站式开发平台,做的就是把这段路接上:环境免安装,浏览器打开即为完整的 Linux 运行环境,预置的 AI 智能体开箱即用。第一个任务建议选能出结果的:做一个游戏、生成一个页面、创建一台实例,从需求走到可访问的链接,一次就能看清这个环境在做什么。沙箱是一个完整的 Linux 环境,依赖、服务、端口都是真实的,不是模拟。环境释放后,权限随之失效。

华为云官方博客 426

华为云码道配置自定义大模型,四种方式完整实操

案例介绍。

华为云官方博客 624

图数据库:实现穿透式监管的数据基座

穿透式监管标志着国企监管从“管企业”向“管资本”转型过程中的关键一跃。而图数据库正是这一跃的技术支点。从股权穿透到资金链穿透,从供应链穿透到数据穿透,华为GES图数据库正在将“穿透式监管”从理念变为可落地、可操作的实践。无论是天眼查式的全量链路查询,还是某集团财经的税务规则判断,抑或是芯片供应链式的部件风险分析,乃至通过Palantir构建决策知识图谱,其底层逻辑都是一致的——用图的力量,穿透一切形式的“隔离层”,直抵风险本质与责任核心。

华为云官方博客 664

《公共云三十问》正式收官,奔赴企业AI百场景新征程

今年6月底,公共云产业联盟重点推出《公共云三十问》专栏,以每周三问的节奏,连载十周,解读《先进公共云》白皮书,分享国计民生系列案例,旨在凝聚共识、推动落地实践。同时,专栏分析公共云在产业升级、民生福祉、科技创新、全球发展等方面的作用,梳理中国特色公共云发展路径:以普惠云拓展用云广度,以智算云提升用云深度,以自主云夯实用云厚度,以全球云打开用云跨度。这十问从专属云、行业云切入,深入政务、金融、交通、电力、钢铁、化工、油气、制造等国计民生场景,回答公共云“怎么用”。

华为云官方博客 473

开发者小技巧|IAM配置,让码道代码智能体连续30天免登录

案例介绍。

华为云官方博客 645

码道深度对接CodeArts,让需求自动落地为代码

案例介绍。

华为云官方博客 720

【公共云三十问 之三十】拥抱AI,企业如何建设面向智能体的专属云?

企业可分阶段建设覆盖开发、运行、运营及安全的一体化智能体平台——从构建一站式、高低码协同的智能体开发平台,到打造高性能、极致弹性的运行时环境,再到搭建AgentOps驱动的持续运营与运维体系,同时构建端到端、多层次的全链路安全防护体系。在数据湖建设方面,遵循“存量复用、平滑演进、AI导向、分步迭代”原则,分三阶段推进——打造AI多模数据湖核心能力、完成存算分离与统一元数据管理、实现闭环赋能全面支撑智能体规模化落地,在保护既有投资的前提下将传统数据平台转型为AI数据专属供给平台。

华为云官方博客 823

【公共云三十问 之二十九】国计民生之制造:制造云如何重塑数智时代的新质生产力?

平台打通软件交付的完整路径,覆盖需求管理、代码托管、代码检查、编译构建、制品仓库、部署、测试等关键环节,支持大模型能力融入研发全流程,实现从需求到交付的端到端管理。通过构建“研发一朵云”,方案打破地域与组织壁垒,实现跨团队协同开发,有效缩短软件交付周期,助力工业制造企业从“传统研发”走向“敏捷研发”,加速数智化转型进程。当制造云真正成为数据流通的平台、AI创新的底座,公共云的社会价值将从基础设施层向生产场景层持续延伸,为新型工业化建设和制造强国战略注入源源不断的动力,重塑数智时代的中国制造新质生产力。

华为云官方博客 789

告别重复手工迁仓,码道MCP+Skill实现仓库批量迁移

案例介绍。

华为云官方博客 790

【公共云三十问 之二十八】国计民生之油气:智算云如何叩响数智时代的“地心蓝金”?

西南油气田以“向地球深部要资源”为战略方向,联合以华为云Stack为代表的公共云服务商共同打造统一算力底座,建设西南区域数据湖与通用技术平台,构建“勘探开发工程技术、天然气生产过程管控、天然气产运储销”等三个一体化协同应用场景,支撑油气勘探、开发生产、管输储运等全业务链的数智化转型。当智算云真正成为数据流通的平台、AI创新的底座,油气田得以将算力效能、数据价值与智能技术深度融入勘探开发全链条,将“看不见的算力”转化为“摸得着的储量”,以智能化手段持续降低勘探风险、缩短发现周期、提高采收效率,确保生产安全。

华为云官方博客 613

【公共云三十问 之二十七】国计民生之化工:数智云如何重塑传统化工新范式?

在架构方面,方案构建云边协同的统一体系,涵盖AI协同、数据协同与运营协同三大维度——总部集中训练大模型,边缘节点负责推理执行,云边持续迭代,实现“边用边学”的智能闭环,模型平均精度提升20%以上。此外,方案提供一站式企业级工业物联网平台、数据湖与数据治理平台,覆盖工业数据分析“采、存、算、管、用”全流程,打通生产现场与管理系统间的数据壁垒,有效消除数据孤岛。层面,方案充分发挥软硬协同优势,实现计算、存储、网络与云平台的深度协同,训练线性度超95%,为大模型训练推理提供强劲算力支撑。▲化工“数智”新模式。

华为云官方博客 663

【公共云三十问 之二十六】国计民生之钢铁:数智云如何淬炼中国钢铁新力量?

同时,构建云边端协同的统一架构,支撑集团总部与各生产基地两级协同发展——总部集中训练大模型,边缘节点负责推理执行,云边持续迭代,实现训推一体化的资源调度与高效协同,为钢铁行业的数智化转型构建了坚实的算力底座。层面,方案构建覆盖“工业数采→边缘IT/OT融合→统一数据湖→数据治理平台→数据应用”全链路的一站式数据治理与流通平台,打通生产现场与管理系统间的数据壁垒,让数据“采得到、流得动、用得好”,加速数据价值从生产现场向经营决策层流动释放。湘潭钢铁集团的钢铁数智云,是钢铁工业智能云建设的标杆案例。

华为云官方博客 526

LakeWatch——MRS 智能运维Agent

从资源池、队列、作业等多个维度,对集群CPU与内存资源进行精细化分析与对比,直观呈现不同时间段的空闲、满载等使用状态,识别资源浪费,指导治理优化,为扩缩容决策提供数据支撑。对HDFS存储进行多维度深度分析(目录、用户、用户组等),涵盖使用量、增量、文件大小分布及数据热度等指标,帮助快速识别增长较快的目录、长期未访问的文件,统计目录文件数量与小文件占比,评估HDFS总存储量与扩缩容需求,为存储治理与资源规划提供全面数据支撑。Agent主动巡检,识别异常趋势并提前预警,让运维从"事后处理"转向"事前预防"。

华为云官方博客 515

华为云专题文档发布:丰富的AI案例、选型指导和概念解读

发布 “云服务选型”、“云计算概念”专题,提供云服务选型指导,助您选择匹配业务的云服务,解读云计算相关概念,开启云上学习之路。开发者工具和文档专区上线,提供从学习、实践到反馈的全链路支持。帮助中心新增100余篇AI案例。

华为云官方博客 286

一个人,也能用AI做点“星东西”

华为云星耀创想者大赛-2026华为云OPC创意大赛等你来~

华为云官方博客 290

从需求到可执行工作项:MCP+Skill 让智能体规划真正落地

回顾整个体验,以前让智能体帮我拆需求,它是洋洋洒洒给我列了一大篇 Markdown,看着挺像那么回事,但最后还是得我一条条往 CodeArts Req 里搬,搬完再手动挂父子关系、排日期,拆需求五分钟,搬运两小时。现在好了,MCP 给智能体接上了"手",Skill 给它装上了"项目经理的脑子",一句话下去,34 个工作项连带排期、层级关系全给我建好了,甘特图一拉,齐刷刷都在两周内,节省了多少工作量啊,美滋滋。本次实操在码道代码智能体基础上,构建了一套"需求→可执行工作项"的自动化规划方案。

华为云官方博客 576

华为云码道「码力续航计划」更新!

✅上新GLM‑5.3‑Flash,高速响应,代码生成、工程解析、Agent调试高效输出。新增GLM‑5.3‑Flash福利模型,每日解锁1000万免费Tokens。● 本次活动共发放总量价值100万元Tokens,发完即止!把耗算力的编码重活,交给华为云码道代码智能体🚀🚀。● 每日额度准时刷新,当日清零、次日满血重置。✅复杂算法、大项目解析、批量代码生成随便跑。✅不用抠额度、不用算消耗,放开调试大胆迭代。✅无需额外操作,登录即送,直接切换模型使用。● 把算力交给码道,让撸码不再内耗👏🏻。

华为云官方博客 686

【公共云三十问 之二十四】国计民生之交通:交通云如何铺就数智通衢新坦途?

交通行业作为支撑实体经济的关键基础设施,涵盖公路、铁路、机场、港口、地铁等众多子领域,其中,公路网络作为综合交通运输体系的基础骨架,承担着全国超过70%的客货运量,其数字化、智能化转型的需求尤为迫切。方面,提供Agent开发框架、知识库管理、RAG工程、意图识别、静态应用编排及模型评测等能力,支持客户将行业知识、业务流程与AI能力深度融合,快速构建面向收费稽核、路网调度、应急处置等场景的智能应用。开发并实现落地应用,全面覆盖建设、管理、养护、运营、服务、安全、办公七大业务领域。

华为云官方博客 461

【公共云三十问 之二十五】国计民生之电力:电力云如何点亮数智电力新引擎?

方案构建了覆盖数据获取、质量评估到标准化处理的全链路能力。基于公共云服务商智算底座及气象大模型,通过时空图神经网络重新建模产流机制,中国华电建成超50TB多源融合数据集,突破时空建模与机理融合等五大关键技术,短期径流预测精度较传统机理模型提升5个百分点以上,实现15天中期径流预测精度超85%,推理效率达秒级。基于气象大模型的基础架构与预训练能力,客户可直接在大模型之上开展增量训练与微调,充分利用场站所在区域的高精度历史数据(如3公里、1公里分辨率),针对不同场站和区域的地形地貌与气候特征进行模型调优。

华为云官方博客 381
上一篇: MySQL事务处理特性的实现原理
下一篇: 想要成为架构师?先看看这些条件满不满足!
华为云开发者联盟
华为云开发者联盟 企业官方账号 企业官方账号
博客等级 码龄10年 72万+粉丝 5985原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值