鴻蒙HarmonyOS實戰-Stage模型(執行緒模型)

蜀道山QAQ發表於2024-05-27

🚀前言

執行緒是計算機中的一種執行單元,是作業系統進行排程的最小單位。它是程序中的實際執行單位,每個程序可以包含多個執行緒。執行緒可以理解為程序中的一個執行流,它獨立執行,擁有獨立的棧和暫存器,但共享程序的資源,如記憶體空間、檔案等。執行緒透過併發執行,將一個程序的任務劃分成多個子任務並行處理,以提高程式的效能和響應速度。

執行緒分為使用者執行緒和核心執行緒。使用者執行緒是由使用者級執行緒庫實現和排程的,作業系統並不直接支援使用者執行緒,因此執行緒的建立、銷燬、排程等都是由應用程式自己完成。核心執行緒則由作業系統核心管理,作業系統負責執行緒的建立、銷燬和排程。核心執行緒相對於使用者執行緒更加穩定和可靠,但建立和銷燬執行緒的開銷較大。

執行緒具有以下特點:

  1. 輕量級:執行緒建立和銷燬的開銷較小,所需的資源較少。
  2. 併發執行:多個執行緒可以同時執行,透過在不同的CPU核心上執行,充分利用多核處理器的效能。
  3. 共享資源:執行緒可以訪問和共享程序的資源,如堆記憶體、全域性變數、檔案等。
  4. 通訊簡單:執行緒之間可以透過共享記憶體進行通訊,也可以使用同步機制如互斥鎖、訊號量等進行協調和同步。
  5. 上下文切換:執行緒之間需要進行切換執行,由於執行緒的切換開銷較小,因此可以快速響應和處理任務。

執行緒的使用可以有效地提高程式的效能和資源利用率,特別適用於多工併發處理的場景,如網路伺服器、圖形介面應用、多媒體處理等。但執行緒程式設計也存在一些挑戰和風險,如執行緒安全、共享資源競爭等問題,需要合理地設計和管理執行緒使用,以保證程式的正確性和穩定性。

🚀一、執行緒模型

🔎1.概述

HarmonyOS應用中,每個程序都有一個主執行緒,主執行緒具有以下職責:

  1. 執行UI繪製:主執行緒負責處理應用介面的繪製操作,包括佈局、繪製和重新整理等。

  2. 管理主執行緒的ArkTS引擎例項:主執行緒透過管理ArkTS引擎例項,使得多個UIAbility元件能夠在主執行緒上執行,實現介面的展示和互動。

  3. 管理其他執行緒的ArkTS引擎例項:主執行緒還負責管理其他執行緒(例如Worker執行緒)的ArkTS引擎例項,包括啟動和終止其他執行緒。

  4. 分發互動事件:主執行緒接收使用者的互動事件,如點選、滑動等,並將這些事件分發給相應的UIAbility進行處理。

  5. 處理應用程式碼的回撥:主執行緒負責處理應用程式碼的回撥函式,包括事件處理和生命週期管理。例如,當使用者觸發某個事件時,主執行緒會呼叫相應的回撥函式進行處理。

  6. 接收Worker執行緒傳送的訊息:主執行緒與Worker執行緒之間透過訊息機制進行通訊,主執行緒接收並處理Worker執行緒傳送的訊息。

除了主執行緒之外,還有一類與主執行緒並行的獨立執行緒,稱為Worker執行緒。Worker執行緒主要用於執行耗時操作,但不可以直接操作UI。Worker執行緒在主執行緒中建立,與主執行緒相互獨立。一個程序最多可以建立8個Worker執行緒。

image

目前,HarmonyOS提供了兩種執行緒間通訊的方式,分別是Emitter和Worker。

  1. Emitter(發射器):Emitter主要適用於執行緒間的事件同步。它可以在不同的執行緒之間傳遞事件,並確保事件的順序和同步性。透過Emitter,一個執行緒可以觸發一個事件,然後其他執行緒可以監聽並處理這個事件。這有助於不同執行緒之間的資料共享和協調。

  2. Worker(工作者):Worker主要用於新開一個執行緒執行耗時任務。當需要執行一些耗時操作時,為了不阻塞主任務的執行,可以使用Worker執行緒。Worker執行緒是在主執行緒的上下文中建立的獨立執行緒,它可以執行一些耗時任務,如網路訪問、檔案讀寫等。工作執行緒可以與主執行緒並行執行,以提高應用的響應性和效能。

🔎2.Emitter

🦋2.1 訂閱事件

import emitter from "@ohos.events.emitter";

// 定義一個eventId為1的事件
let event = {
    eventId: 1
};

// 收到eventId為1的事件後執行該回撥
let callback = (eventData) => {
    console.info('event callback');
};

// 訂閱eventId為1的事件
emitter.on(event, callback);

🦋2.2 傳送事件

import emitter from "@ohos.events.emitter";

// 定義一個eventId為1的事件,事件優先順序為Low
let event = {
    eventId: 1,
    priority: emitter.EventPriority.LOW
};

let eventData = {
    data: {
        "content": "c",
        "id": 1,
        "isEmpty": false,
    }
};

// 傳送eventId為1的事件,事件內容為eventData
emitter.emit(event, eventData);

🔎3.Worker

🦋3.1 配置檔案

以下配置檔案都是在build-profile.json5中的
image

"buildOption": {
  "sourceOption": {
    "workers": [
      "./src/main/ets/workers/worker.ts"
    ]
  }
}

🦋3.2 建立檔案

worker.ts檔案

import worker from '@ohos.worker';

let parent = worker.workerPort;

// 處理來自主執行緒的訊息
parent.onmessage = function(message) {
    console.info("onmessage: " + message)
    // 傳送訊息到主執行緒
    parent.postMessage("message from worker thread.")
}

🦋3.3 使用執行緒模型

import worker from '@ohos.worker';

let wk = new worker.ThreadWorker("entry/ets/workers/worker.ts");

// 傳送訊息到worker執行緒
wk.postMessage("message from main thread.")

// 處理來自worker執行緒的訊息
wk.onmessage = function(message) {
    console.info("message from worker: " + message)

    // 根據業務按需停止worker執行緒
    wk.terminate()
}

注意:build-profile.json5中配置的worker.ts的相對路徑都為./src/main/ets/workers/worker.ts時,在Stage模型下建立worker需要傳入路徑entry/ets/workers/worker.ts;

🚀寫在最後

  • 如果你覺得這篇內容對你還蠻有幫助,我想邀請你幫我三個小忙:
  • 點贊,轉發,有你們的 『點贊和評論』,才是我創造的動力。
  • 關注小編,同時可以期待後續文章ing🚀,不定期分享原創知識。
  • 更多鴻蒙最新技術知識點,請關注作者部落格:https://t.doruo.cn/14DjR1rEY

image

相關文章