本文旨在深入探討華為鴻蒙HarmonyOS Next系統(截止目前API12)的技術細節,基於實際開發實踐進行總結。主要作為技術分享與交流載體,難免錯漏,歡迎各位同仁提出寶貴意見和問題,以便共同進步。本文為原創內容,任何形式的轉載必須註明出處及原作者。
鴻蒙系統提供了兩種併發能力:TaskPool 和 Worker。它們都基於 Actor 併發模型實現,但它們的使用場景和功能有所不同。
- TaskPool:TaskPool 是一個多執行緒執行環境,它提供了任務的執行、取消、優先順序設定等功能。TaskPool 適用於獨立任務,例如計算密集型任務、I/O 密集型任務等。
- Worker:Worker 是一個可以長時間執行的後臺執行緒,它支援與宿主執行緒之間的訊息傳遞。Worker 適用於長時間執行的任務,例如後臺資料處理、模型訓練等。
TaskPool 和 Worker 的區別與使用場景
特性 | TaskPool | Worker |
---|---|---|
記憶體模型 | 執行緒間隔離,記憶體不共享 | 執行緒間隔離,記憶體不共享 |
引數傳遞機制 | 採用標準的結構化克隆演算法(Structured Clone)進行序列化、反序列化,完成引數傳遞。支援 ArrayBuffer 轉移和 SharedArrayBuffer 共享。 | 採用標準的結構化克隆演算法(Structured Clone)進行序列化、反序列化,完成引數傳遞。支援 ArrayBuffer 轉移和 SharedArrayBuffer 共享。 |
引數傳遞 | 直接傳遞,無需封裝,預設進行 transfer。 | 訊息物件唯一引數,需要自己封裝。 |
方法呼叫 | 直接將方法傳入呼叫。 | 在 Worker 執行緒中進行訊息解析並呼叫對應方法。 |
返回值 | 非同步呼叫後預設返回。 | 主動傳送訊息,需在 onmessage 解析賦值。 |
生命週期 | TaskPool 自動管理生命週期,無需關心任務負載高低。 | 開發者自行管理 Worker 的數量及生命週期。 |
任務池個數上限 | 自動管理,無需配置。 | 同個程序下,最多支援同時開啟 64 個 Worker 執行緒,實際數量由程序記憶體決定。 |
任務執行時長上限 | 3 分鐘(不包含 Promise 和 async/await 非同步呼叫的耗時,例如網路下載、檔案讀寫等 I/O 任務的耗時),長時任務無執行時長上限。 | 無限制。 |
設定任務的優先順序 | 支援配置任務優先順序。 | 不支援。 |
執行任務的取消 | 支援取消已經發起的任務。 | 不支援。 |
執行緒複用 | 支援。 | 不支援。 |
任務延時執行 | 支援。 | 不支援。 |
設定任務依賴關係 | 支援。 | 不支援。 |
序列佇列 | 支援。 | 不支援。 |
任務組 | 支援。 | 不支援。 |
使用場景: |
- TaskPool:適用於獨立任務,例如計算密集型任務、I/O 密集型任務等。
- Worker:適用於長時間執行的任務,例如後臺資料處理、模型訓練等。
TaskGroup 的管理與任務優先順序
TaskGroup:TaskGroup 是一個任務集合,可以將多個任務新增到 TaskGroup 中,並一起執行。TaskGroup 支援配置任務的優先順序。
示例:
import { taskpool } from '@kit.ArkTS';
@Concurrent
function add(num1: number, num2: number): number {
return num1 + num2;
}
@Concurrent
function subtract(num1: number, num2: number): number {
return num1 - num2;
}
async function concurrentFunc() {
const task1 = new taskpool.Task(add, 1, 2);
const task2 = new taskpool.Task(subtract, 3, 4);
const group = new taskpool.TaskGroup();
group.addTask(task1);
group.addTask(task2);
group.addTask(task1); // 新增重複任務
await taskpool.execute(group, taskpool.Priority.HIGH);
}
任務優先順序:
- Priority.IDLE:後臺任務,優先順序最低。
- Priority.LOW:低優先順序任務。
- Priority.MEDIUM:中等優先順序任務。
- Priority.HIGH:高優先順序任務。
任務的新增與執行邏輯
任務新增:
const task = new taskpool.Task(func, args);
任務執行:
await taskpool.execute(task);
任務取消:
taskpool.cancel(task);
示例程式碼:透過 TaskPool 執行 CPU 密集型任務的示例
以下是一個簡單的示例,演示如何使用 TaskPool 執行 CPU 密集型任務:
import { taskpool } from '@kit.ArkTS';
@Concurrent
function complexCalculation(data: ArrayBuffer): ArrayBuffer {
// 執行復雜的計算操作
return data;
}
async function concurrentCalculation() {
const data = new ArrayBuffer(1024);
const task = new taskpool.Task(complexCalculation, data);
await taskpool.execute(task);
}
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
.onClick(async () => {
await concurrentCalculation();
})
.width('100%');
}
}
.height('100%');
}
}
這段程式碼定義了一個名為 Index
的元件,並在元件中顯示了一條文字訊息 "Hello World"。點選按鈕會執行 concurrentCalculation
函式,該函式建立一個併發任務並執行它。任務完成後,會在控制檯輸出結果。
總結
透過以上介紹,您可以瞭解到鴻蒙系統中的 TaskPool 和 Worker 併發能力的使用方法。TaskPool 和 Worker 都是基於 Actor 併發模型實現的,但它們的使用場景和功能有所不同。希望本文能夠幫助您掌握鴻蒙系統中的併發程式設計技術,並開發出更優秀的鴻蒙應用。