OpenHarmony轻量系统服务管理|系统服务管理之系统功能管理器详解

前言

  在分布式调度框架中,关于轻量级服务管理的代码总体上可以分为四部分,分别是Samgr、Samgr_client、Samgr_endpoint及Samgr_server。本文是对Samgr部分的总体概述,相关代码文件位于distributedschedule_samgr_lite\samgr.后续对代码进行详细注解。

Samgr总体分析

  在samgr部分,可以将代码分为基础代码和核心代码。基础服务框架代码包括common、service、feature、iunknown、task等文件中的函数,主要的内容是提供一些鸿蒙业务模型的基本函数操作,通过这些定义的函数来完成业务运作。它们的概念通过子主题进行分析,链接在文末。核心代码在samgr_lite文件中,负责系统功能管理器(Samgr)的初始化。当Samgr初始化成功后,会对已注册的服务进行初始化。代码概述如下:

  

复制代码
 1 samgr_lite/
 2 ├── samgr
 3 │   ├── adapter
 4 │   │   ├── cmsis
 5 │   │   │   ├── memory_adapter.c    实现CMSIS下的内存分配和释放函数,引用malloc.h文件
 6 │   │   │   ├── queue_adapter.c        实现CMSIS下消息队列的创建和销毁以及元素出队和入队操作,底层实现依赖cmsis_os.h文件
 7 │   │   │   ├── thread_adapter.c    实现CMSIS下与线程和互斥锁相关的操作函数,底层实现依赖cmsis_os.h文件
 8 │   │   │   └── time_adapter.c        目前仅实现了获取当前时间的函数,底层实现依赖cmsis_os.h文件
 9 │   │   ├── memory_adapter.h        声明内存分配和释放的函数,屏蔽POSIX和CMSIS内存操作的细节差异
10 │   │   ├── posix
11 │   │   │   ├── lock_free_queue.c    实现无锁队列的相关函数,包括队列的创建、元素入队及出队等函数
12 │   │   │   ├── lock_free_queue.h    定义无锁队列结构,并声明无锁队列的创建、判空、判满和入队、出队函数
13 │   │   │   ├── memory_adapter.c    实现POSIX下的内存分配和释放函数,引用stdlib.h文件
14 │   │   │   ├── queue_adapter.c        实现POSIX下消息队列的创建和销毁以及元素出队和入队操作
15 │   │   │   ├── thread_adapter.c    实现POSIX下与线程和互斥锁相关的操作函数,底层实现依赖pthread.h文件
16 │   │   │   └── time_adapter.c        目前仅实现了获取当前时间的函数,底层实现依赖time.h文件
17 │   │   ├── queue_adapter.h            声明消息队列的创建、销毁和元素入队、出队函数,屏蔽POSIX和CMSIS队列操作的细节差异
18 │   │   ├── thread_adapter.h        声明与线程和互斥锁相关的操作函数,屏蔽POSIX和CMSIS线程和互斥锁的细节差异
19 │   │   └── time_adapter.h            声明与时间相关的操作函数,屏蔽POSIX和CMSIS时间操作的细节差异
20 │   ├── registry
21 │   │   ├── service_registry.c        当前文件中未实现与业务注册相关的函数,均以弱引用的方式定义,在其他文件中有强引用的实现
22 │   │   └── service_registry.h        声明与业务注册相关的函数,包括服务接口的注册和查询、系统能力接口的注册和查询
23 │   └── source
24 │       ├── common.c                定义一个简化版的vector容器,包括创建vector、添加元素、查找元素、交换元素、获取元素个数等函数
25 │       ├── feature.c                实现功能(feature)对外接口的增加、查询、删除等操作
26 │       ├── feature_impl.h            声明与featureimpl对象相关的操作函数,包括增加接口、删除接口、获取接口等函数
27 │       ├── iunknown.c                实现与接口(iunknown)相关的操作,包括增加接口的引用、查询接口的信息、减少接口的引用
28 │       ├── message.c                实现与通信消息相关的操作,包括发送请求消息、发送响应消息、接收消息和释放消息等函数
29 │       ├── message_inner.h            定义消息体和消息类型,并声明消息接收和释放函数
30 │       ├── samgr_lite.c            实现系统功能管理(Samgr)模块注册、发现及初始化服务(service)、功能(feature)、对外接口(iunknown)相关的函数
31 │       ├── samgr_lite_inner.h        是对samgr_lite.h的补充,在samgr_lite.h中定义了一个SamgrLite结构体,用于注册/注销服务、注册/注销功能、注册/注销对外接口等。
32                                     在当前头文件中定义一个SamgrLiteImpl结构体,包含存储服务的容器以及任务池等信息。
33 │       ├── service.c                实现操作服务实例(serviceimpl)及其下属功能实例(featureimpl)的相关函数,包括创建服务实例、注册功能实例、停止服务实例等函数
34 │       ├── service_impl.h            定义服务实例结构体,并声明操作服务实例(serviceimpl)及其下属功能实例(featureimpl)的相关函数
35 │       ├── task_manager.c            实现任务池和消息处理的相关函数,包括创建任务池、启动任务池、引用/释放任务池、处理请求消息、处理响应消息等函数
36 │       └── task_manager.h            定义任务池结构体,并声明创建任务池、启动任务池、引用任务池等相关函数
复制代码

Samgr_lite机制分析

  Samgr是分布式调度中的重要成员,负责服务和功能的维护、注册和发现。鸿蒙系统的业务模型包含三大对象,分别是服务(service)、功能(feature)和对外接口(iunknown),所有的对外接口都要注册到指定的功能或服务的默认接口,而所有的功能都需要注册到相应的服务中,最后服务需要注册到Samgr中,经过初始化后服务开始向外提供功能。可以看到Samgr是注册和发现的核心。要想讲清楚Samgr的作用和机制就需要结合具体的服务,从服务的创建、注册和初始化等过程来分析它,这里以广播服务为例详细讲解它们的关联以及服务和Samgr从创建到启动的全过程。>看这里),分别是服务(service)、功能(feature)和对外接口(iunknown),所有的对外接口都要注册到指定的功能或服务的默认接口,而所有的功能都需要注册到相应的服务中,最后服务需要注册到Samgr中,经过初始化后服务开始向外提供功能。可以看到Samgr是注册和发现的核心。要想讲清楚Samgr的作用和机制就需要结合具体的服务,从服务的创建、注册和初始化等过程来分析它,这里以广播服务为例详细讲解它们的关联以及服务和Samgr从创建到启动的全过程。

  首先我们需要自定义一个静态全局的广播服务,并赋值生命周期函数,它将会注册到Samgr中。当系统启动时,在Samgr部分从SYS_SERVICE_INIT(Init)函数进入服务初始化过程,在Init()函数中通过SAMGR_GetInstance()获取Samgr的系统能力管理类实例。在获取实例的过程中,若g_samgrImpl还未初始化,则触发它的Init()函数,初始化它的成员变量。然后调用系统能力管理类实例中的RegisterService函数,将广播服务注册到Samgr的服务集合中。这里就完成了广播服务的本地注册过程。

  

 

系统功能管理器(samgr)初始化完毕后。Samgr从SAMGR_Bootstrap(void)启动,这是系统功能管理器的启动入口。先更新Samgr的状态,从BOOT_SYS进入BOOT_SYS_WAIT状态,然后收集所有注册在Samgr中且处于SVC_INIT状态的服务,进入InitializeAllServices()函数初始化它们。服务初始化的整个过程可以分为三个操作。

  第一,为服务绑定指定的任务池并启动任务池中的处理线程。服务必须要有自己的线程才可以执行业务逻辑,所以我们需要为它分配一个任务池,任务池中包含了线程以及对应的消息队列,服务接收并处理消息完成业务功能。每个服务创建的时候都会指定任务配置信息,根据不同的任务类型分配相应的任务池。任务类型有以下三种:

    1.SHARED_TASK,根据service的优先级共享任务,此时绑定的是SamgrLiteImpl中维护的共享任务池。

    2.SPECIFIED_TASK,为service绑定指定的任务池,遍历所有的ServiceImpl对象,查找相同任务配置的任务池,若找到则绑定,若未找到则创建新的任务池。

    3.SINGLE_TASK,根据任务配置,创建新的任务池并绑定

  第二,调用服务和功能自身的初始化函数。我们可以根据业务需要自定义服务和功能的初始化函数。

  第三,向知名Endpoint注册服务和功能的信息,完成服务的远程注册过程。Endpoint是鸿蒙操作系统进程间通信的对外端点,用于标识进程的通信地址。如果进程间要进行通信,就需要知道目的进程对外的通信端点Endpoint的地址,而知名Endpoint就是我们人为设定的固定地址。所有的Endpoint都要向知名endpoint注册自己的地址,由知名Endpoint提供地址查询服务。

  

 

  在服务的初始化过程中,当服务绑定任务池以后会有一个分叉。如果服务绑定任务池成功,那么它就有了对应的执行线程和消息队列。在进行初始化时,会将服务的初始化请求封装为Exchange对象,然后插入到对应的消息队列中,由对应的任务池线程接收并执行回调函数(用于初始化服务的函数)。如果服务绑定任务池失败,那么就在当前线程中直接调用服务的初始化函数。

  当所有的系统服务初始化完成后,Samgr就从BOOT_SYS_WAIT进入BOOT_APP阶段。服务从SVC_INIT状态进入SVC_IDLE状态,此时服务可以正常执行业务功能。

  

 

posted @   沉心慢慢  阅读(663)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示