1. 程式人生 > 其它 >OpenHarmony輕量系統服務管理|系統服務管理之系統功能管理器詳解

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狀態,此時服務可以正常執行業務功能。