更多内容请访问:与华为官方共建的鸿蒙技术社区https://harmonyos.51cto.com接下来我们来看看启动过程管理器g_server(包括samgrEP)并提供外部服务。foundation进程作为client向managerg_server注册,和上篇文章《系统服务框架子系统-8-client EP的注册》一模一样,只是服务和特性多了很多。这次我们是分析流程并对照日志进行验证(日志文件也在上面-8的附件中)。由于任务调度,日志会有点交叉和混乱,但是同一个service/feature的日志,在timeline上的顺序是没有问题的,可以通过关键词搜索过滤掉。SamgrServerg_server是samgr_server.c文件中唯一的全局管理器服务对象。它包含在基础流程所依赖的大量服务和功能中。在基础进程运行main之前,它首先运行它所依赖的所有服务和功能。feature的Init,运行到samgr_server.c的SYS_SERVICE_INIT(InitializeRegistry)时:大致分为4个部分:[4-1]SASTORA_Init(&g_server.store)这是一个链表+vector结构,后面会详细介绍后来,暂时没有打印日志。[4-2]g_server.samgr=SAMGR_CreateEndpoint("samgr",RegisterSamgrEndpoint),为g_server创建一个EP,因为这个EP很特殊,是知名EP,这里需要创建,但是一直没有开始“向自己注册自己”。[4-3]RegisterService((Service*)&g_server),向本进程(基础)的g_samgrImpl注册服务。[4-4]创建VectorsysCapabilitys,调用ParseSysCap()读取分析“/etc/system_capability.json”文件,根据格式将系统Capabilities添加到VectorsysCapabilities中。“/etc/system_capability.json”文件是“//foundation/distributedschedule/samgr_lite/config/system_capability.json”文件的副本。运行日志如下:接下来等待foundation进程运行main()函数,调用SAMGR_Bootstrap()为其依赖的所有服务(包括samgr)创建线程和消息队列:inall基础所依赖的服务(甚至整个用户态下面的所有线程中),只有samgr线程的任务优先级是PRI_BUTT-1=38:TaskConfigconfig={LEVEL_HIGH,PRI_BUTT-1,0x400,20,SINGLE_TASK};看PRI_BUTT的定义就知道,通信相关的线程(也就是各个EP中的boss线程)的优先级为PRI_ABOVE_NORMAL,而samgr是通信的关键节点,它的优先级更高,接近于“优先级上限”,这也体现了通讯效率在鸿蒙系统中的最高地位。前面“线程/进程间通信模型”中提到的线程只有0到31的级别,数字越小,优先级越高。这里怎么能超过31级,数字越大优先级越高?"SAMGR_LINUX_ADAPTER"定义在//foundation/distributedschedule/samgr_lite/samgr/adapter/BUILD.gn:if(ohos_kernel_type=="linux"){defines+=["SAMGR_LINUX_ADAPTER"]}上面定义的TaskPriority是标准系统使用Linux内核时使用的线程优先级的定义,而LiteOS_A内核的小系统会做一个转换,使用一个级别来自0到31代表线程优先级。这样转换后,samgr在小系统中的线程优先级为1,还是很高级的(更高级别的0级可能是内核的某个线程,我没深挖)。因此,samgr服务的任务创建后,首先会被系统调度运行其初始化,即运行DEFAULT_Initialize()过程:四步,因为“NOFeature”,所以只运行前两步,但是第一步运行的samgr服务的Initialize()函数有点特殊:它比其他服务的Initialize()函数多运行一个SAMGR_AddRouter(...,GET_IUNKNOWN(*server)),并且需要特别注意第四个参数:GET_IUNKNOWN(*server),这个参数可以保证proxy满足要求,保证这个router可以正确的加入到managerg_server->samgr的EP的Vectorrouters中。在SAMGR_AddRouter()中,确保满足条件后,将路由器添加到Vector路由器中,然后Listen(endpoint)。这是众所周知的EP的第一个(也是唯一一个)路由器,所以会创建一个boss线程,然后运行Receive()Entrance。因为线程调度,Receive()的过程运行得稍微晚一些,也是内外两层while循环,但是因为内层执行的registerEP函数指针指向RegisterSamgrEndpoint(),即samgrEP给自己注册,所以很快就OK了:此时g_server的知名EP是这样的:因为是知名EP,没有Feature,第三步Receive()也跳过了,直接启动了StartLoop,它开始接收早其另一个EP(ipcclient)的IPC注册报文,由Dispatch()函数处理(后面会做进一步分析),所以在接下来的日志中,可以看到:在跑到知名EP之前注册了自己的客户端EP,经过多次重试,终于注册成功了自己的句柄。回到samgr的DEFAULT_Initialize()过程的第二步:DEFAULT_Initialize_samgr->RegServiceApi(ServiceImpl->defaultApi[0])实际调用的是:SAMGR_RegisterServiceApi(...,ServiceImpl->defaultApi)其中defaultApi为NULL,原因和上一篇Broadcast服务的defaultApi为NULL一样。三步过程中,第一步,初始化foundation进程自己的g_remoteRegister,并为其创建一个clientEP。这个EP是一个普通的客户端EP,是基础进程对外进行IPC的通信终端。虽然和上面的服务器EP在基础流程上是不同的,从上图就可以看到《线程/进程间通信模型》。三步过程中,在第二步中,因为defaultApi为NULL,所以会添加router失败,不会为clientEP创建boss线程。直到第一个路由器成功添加到后续服务中,才会创建老板。线。接下来是基础进程的其他服务,通过各自的消息队列接收Init消息,通过[samgr_lite]HandleInitRequest:Initing_Service...运行自己的DEFAULT_Initialize()进程,与客户端EP的注册过程完全一样,但是在这个过程中有很多服务/功能。系统调度后,打印的日志会有一些交集,分析起来会有些乱,但是这个过程非常清晰,可以通过搜索关键字进行过滤验证。更多信息请访问:Harmonyos.51cto.com,与华为官方合作打造的鸿蒙技术社区