OpenHarmony輕量系統服務管理|鴻蒙業務模型重要概念
前言
在針對鴻蒙分散式任務排程的原始碼分析中,發現它業務邏輯的實現圍繞著三大概念展開,分別是服務(Service)、功能(Feature)和功能介面API(Iunknown)。所以理解並掌握這三個概念對於我們深入學習鴻蒙底層程式碼的業務邏輯有極大的幫助。下面將結合前期分析鴻蒙程式碼的經驗,通過圖文並茂的方式為讀者講解它們的基類和例項物件以及相應的作用。
結構分析
Service
服務(Service)是鴻蒙作業系統中業務邏輯的核心,是一組功能或操作的集合。下面的結構體定義了服務的相關函式指標。
1 struct Service { 2 const char *(*GetName)(Service *service); //獲取服務名稱 3 BOOL (*Initialize)(Service *service, Identity identity); //初始化服務 4 BOOL (*MessageHandle)(Service *service, Request *request); //處理服務的訊息 5 TaskConfig (*GetTaskConfig)(Service *service); //獲取服務的任務配置 6 };
Feature
一個服務可以擁有多個功能(Feature),功能是業務的執行單元。由各式各樣的功能組合成一個完整的服務。下面的結構體定義了功能介面的相關函式指標。
struct Feature { const char *(*GetName)(Feature *feature); //獲取功能名稱 void (*OnInitialize)(Feature *feature, Service *parent, Identity identity); //初始化功能 void (*OnStop)(Feature *feature, Identity identity); //停止功能 BOOL (*OnMessage)(Feature *feature, Request *request); //處理功能訊息 };
IUnknown
通過上述服務和功能的概念抽象出鴻蒙完整的業務邏輯模型。一個服務包含零個到多個功能。在鴻蒙程式碼中,針對服務和功能的呼叫還提供了統一的對外介面(Iunknown)。
1 struct IUnknown { 2 int (*QueryInterface)(IUnknown *iUnknown, int version, void **target);//查詢指定版本的IUnknown介面的子類物件 3 int (*AddRef)(IUnknown *iUnknown); //新增引用計數 4 int (*Release)(IUnknown *iUnknown); //釋放引用計數 5 };
例項物件
在後續服務和功能的註冊、啟動等過程中都是使用ServiceImpl和FeatureImpl。它們的定義如下:
功能繫結介面後的例項物件
一個功能對應一個介面,作為一個功能的例項物件
1 struct FeatureImpl { 2 Feature *feature; //功能物件 3 IUnknown *iUnknown; //對外的介面 4 };
服務繫結介面後的例項物件
一個服務至少向外提供一個API介面(當服務下面沒有註冊功能時,向外暴露defaultApi)。也可以提供多個API介面(當服務下面註冊多個功能時,每一個功能都有一個API介面)。一個服務對應一個任務池。
1 struct ServiceImpl { 2 Service *service; //服務物件 3 IUnknown *defaultApi; //預設的對外介面 4 TaskPool *taskPool; //繫結的任務池 5 Vector features; //已註冊的FeatureImpl物件 6 int16 serviceId; //服務ID,位於g_samgrImpl的vector中的下標 7 uint8 inited; //服務所處的狀態 8 Operations ops; //操作資訊,記錄一些運維資訊 9 };
服務和功能例項物件的圖示
ServiceImpl:Vector的data指向一個FeatureImpl型別的指標陣列,每個指標指向一個FeatureImpl物件。TaskPool指向一個TaskPool物件。圖中只畫出了部分重要欄位。
注:任務池的繫結分為三種:
1.SHARED_TASK,根據service的優先順序共享任務,此時繫結的是SamgrLiteImpl中維護的共享任務池。
2.SPECIFIED_TASK,為service繫結指定的任務池,遍歷所有的ServiceImpl物件,查詢相同任務配置的任務池,若找到則繫結,若未找到則建立新的任務池。
3.SINGLE_TASK,根據任務配置,建立新的任務池並繫結
註冊過程
這裡先簡單的介紹一下服務和功能的註冊,在後續文章中再詳細介紹函式的呼叫過程。提到服務的註冊我們還需要了解一個重要的資料結構SamgrLiteImpl,在程式碼中有一個由它定義的全域性變數g_samgrImpl,這個全域性變數維護了一系列的服務,也稱為系統功能管理器(Samgr)。結構體定義如下:
1 struct SamgrLiteImpl { 2 SamgrLite vtbl; //SamgrLite類管理一些函式,用於註冊和發現服務和功能 3 MutexId mutex; //互斥鎖 4 BootStatus status; //系統功能管理器(samgr)的狀態 5 Vector services; //已註冊的ServiceImpl物件 6 TaskPool *sharedPool[MAX_POOL_NUM]; //服務共享的任務池 7 };
註冊的過程分為介面的註冊、功能的註冊和服務的註冊。流程如下:
1.Feature繫結IUnknown封裝為FeatureImpl物件。(介面的註冊)
2.將FeatureImpl物件新增到ServiceImpl的vector集合中。(功能的註冊)
3.將ServiceImpl物件新增到SamgrLiteImpl的vector集合中。(服務的註冊)
Samgr例項圖示
SamgrLiteImpl:Vector的data指向一個ServiceImpl型別的指標陣列,每個指標指向一個ServiceImpl物件。TaskPool指向一個TaskPool型別的指標陣列,每個指標指向一個TaskPool,這一點與ServiceImpl中是不同的。圖中只畫出了部分重要欄位。
注:當ServiceImpl中task的taskflags即任務型別為SHARED_TASK時,根據任務的優先順序共享SamgrLiteImpl中TaskPool維護的指定任務池。