鴻蒙程式設計江湖:併發程式設計基礎與鴻蒙中的任務併發

SameX發表於2024-10-25

本文旨在深入探討華為鴻蒙HarmonyOS Next系統(截止目前API12)的技術細節,基於實際開發實踐進行總結。主要作為技術分享與交流載體,難免錯漏,歡迎各位同仁提出寶貴意見和問題,以便共同進步。本文為原創內容,任何形式的轉載必須註明出處及原作者。

併發程式設計是指在同一時間段內處理多個任務的能力。併發程式設計可以提高應用程式的響應速度和效率,並避免耗時任務阻塞主執行緒,導致應用程式卡頓。
鴻蒙系統提供了多種併發模型,其中 TaskPool 和 Worker 是兩種常用的併發能力。

  • TaskPool:TaskPool 是一個多執行緒執行環境,它提供了任務的執行、取消、優先順序設定等功能。TaskPool 適用於獨立任務,例如計算密集型任務、I/O 密集型任務等。
  • Worker:Worker 是一個可以長時間執行的後臺執行緒,它支援與宿主執行緒之間的訊息傳遞。Worker 適用於長時間執行的任務,例如後臺資料處理、模型訓練等。

@Concurrent 裝飾器的用途與用法

在鴻蒙系統中,@Concurrent 裝飾器用於宣告並校驗併發函式。從 API version 9 開始,支援使用 @Concurrent 裝飾器宣告並校驗併發函式。
裝飾器用法

@Concurrent
function myConcurrentFunction() {
  // 併發函式的程式碼
}

裝飾器引數:無。
使用場景:僅支援在 Stage 模型的工程中使用。僅支援在 .ets 檔案中使用。
裝飾的函式型別:允許標註 async 函式或普通函式。禁止標註 generator、箭頭函式、method。不支援類成員函式或者匿名函式。
裝飾的函式內的變數型別:允許使用 local 變數、入參和透過 import 引入的變數。禁止使用閉包變數。
裝飾的函式內的返回值型別:支援的型別請查序列化支援型別。

併發函式的宣告與校驗

併發函式是指可以在 TaskPool 中執行的函式。宣告併發函式需要使用 @Concurrent 裝飾器進行修飾,並進行必要的校驗。
示例

import { taskpool } from '@kit.ArkTS';
@Concurrent
function add(num1: number, num2: number): number {
  return num1 + num2;
}

併發函式注意事項

  • 併發函式必須使用 @Concurrent 裝飾器進行修飾。
  • 併發函式的入參和返回值型別必須支援序列化。
  • 併發函式內不允許使用閉包變數。
  • 併發函式執行時間不能超過 3 分鐘。

Actor 併發模型與記憶體共享模型的對比

Actor 併發模型

  • 每個 Actor 都擁有獨立的記憶體空間。
  • Actor 之間透過訊息傳遞機制進行通訊。
  • Actor 併發模型避免了記憶體競爭問題。
    記憶體共享模型
  • 多個執行緒共享同一塊記憶體空間。
  • 執行緒訪問記憶體需要搶佔鎖。
  • 記憶體共享模型容易出現資料競爭問題。
    對比
  • Actor 併發模型更適合併發程式設計,因為它避免了記憶體競爭問題。
  • 記憶體共享模型更適合共享記憶體的場景,例如多執行緒計算。

TaskPool 中執行併發函式的基本示例

以下是一個簡單的示例,演示如何在 TaskPool 中執行併發函式:

import { taskpool } from '@kit.ArkTS';
@Concurrent
function add(num1: number, num2: number): number {
  return num1 + num2;
}
async function concurrentFunc() {
  try {
    let task: taskpool.Task = new taskpool.Task(add, 1, 2);
    console.info("taskpool res is: " + await taskpool.execute(task));
  } catch (e) {
    console.error("taskpool execute error is: " + e);
  }
}
@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            concurrentFunc();
          })
          .width('100%');
      }
    }
    .height('100%');
  }
}

這段程式碼定義了一個名為 Index 的元件,並在元件中顯示了一條文字訊息 "Hello World"。點選按鈕會執行 concurrentFunc 函式,該函式建立一個併發任務並執行它。任務完成後,會在控制檯輸出結果。

總結

透過以上介紹,您可以瞭解到鴻蒙系統中的併發模型和 @Concurrent 裝飾器的使用方法。使用併發程式設計可以有效地提高應用程式的響應速度和效率,並避免耗時任務阻塞主執行緒。希望本文能夠幫助您掌握鴻蒙系統中的併發程式設計技術,並開發出更優秀的鴻蒙應用。

相關文章