HarmonyOS CPU與I/O密集型任務開發指導
一、CPU密集型任務開發指導
CPU密集型任務是指需要佔用系統資源處理大量計算能力的任務,需要長時間執行,這段時間會阻塞執行緒其它事件的處理,不適宜放在主執行緒進行。例如影像處理、影片編碼、資料分析等。
基於多執行緒併發機制處理CPU密集型任務可以提高CPU利用率,提升應用程式響應速度。
當進行一系列同步任務時,推薦使用Worker;而進行大量或排程點較為分散的獨立任務時,不方便使用8個Worker去做負載管理,推薦採用TaskPool。接下來將以影像直方圖處理以及後臺長時間的模型預測任務分別進行舉例。
使用TaskPool進行影像直方圖處理
1. 實現影像處理的業務邏輯。
2. 資料分段,將各段資料透過不同任務的執行完成影像處理。
建立 Task ,透過 execute() 執行任務,在當前任務結束後,會將直方圖處理結果同時返回。
3. 結果陣列彙總處理。
import taskpool from '@ohos.taskpool'; @Concurrent function imageProcessing(dataSlice: ArrayBuffer) { // 步驟1: 具體的影像處理操作及其他耗時操作 return dataSlice; } function histogramStatistic(pixelBuffer: ArrayBuffer) { // 步驟2: 分成三段併發排程 let number = pixelBuffer.byteLength / 3; let buffer1 = pixelBuffer.slice(0, number); let buffer2 = pixelBuffer.slice(number, number * 2); let buffer3 = pixelBuffer.slice(number * 2); let task1 = new taskpool.Task(imageProcessing, buffer1); let task2 = new taskpool.Task(imageProcessing, buffer2); let task3 = new taskpool.Task(imageProcessing, buffer3); taskpool.execute(task1).then((ret: ArrayBuffer[]) => { // 步驟3: 結果處理 }); taskpool.execute(task2).then((ret: ArrayBuffer[]) => { // 步驟3: 結果處理 }); taskpool.execute(task3).then((ret: ArrayBuffer[]) => { // 步驟3: 結果處理 }); } @Entry @Component struct Index { @State message: string = 'Hello World' build() { Row() { Column() { Text(this.message) .fontSize(50) .fontWeight(FontWeight.Bold) .onClick(() => { let data: ArrayBuffer; histogramStatistic(data); }) } .width('100%') } .height('100%') } }
使用Worker進行長時間資料分析
本文透過某地區提供的房價資料訓練一個簡易的房價預測模型,該模型支援透過輸入房屋面積和房間數量去預測該區域的房價,模型需要長時間執行,房價預測需要使用前面的模型執行結果,因此需要使用Worker。
1. DevEco Studio提供了Worker建立的模板,新建一個Worker執行緒,例如命名為“MyWorker”。
2. 在主執行緒中透過呼叫ThreadWorker的 constructor() 方法建立Worker物件,當前執行緒為宿主執行緒。
import worker from '@ohos.worker'; const workerInstance = new worker.ThreadWorker('entry/ets/workers/MyWorker.ts');
3. 在宿主執行緒中透過呼叫 onmessage() 方法接收Worker執行緒傳送過來的訊息,並透過呼叫 postMessage() 方法向Worker執行緒傳送訊息。
例如向Worker執行緒傳送訓練和預測的訊息,同時接收Worker執行緒傳送回來的訊息。
// 接收Worker子執行緒的結果 workerInstance.onmessage = function(e) { // data:主執行緒傳送的資訊 let data = e.data; console.info('MyWorker.ts onmessage'); // 在Worker執行緒中進行耗時操作 } workerInstance.onerror = function (d) { // 接收Worker子執行緒的錯誤資訊 } // 向Worker子執行緒傳送訓練訊息 workerInstance.postMessage({ 'type': 0 }); // 向Worker子執行緒傳送預測訊息 workerInstance.postMessage({ 'type': 1, 'value': [90, 5] });
4. 在MyWorker.ts檔案中繫結Worker物件,當前執行緒為Worker執行緒。
import worker, { ThreadWorkerGlobalScope, MessageEvents, ErrorEvent } from '@ohos.worker'; let workerPort: ThreadWorkerGlobalScope = worker.workerPort;
5. 在Worker執行緒中透過呼叫 onmessage() 方法接收宿主執行緒傳送的訊息內容,並透過呼叫 postMessage() 方法向宿主執行緒傳送訊息。
如在Worker執行緒中定義預測模型及其訓練過程,同時與主執行緒進行資訊互動。
import worker, { ThreadWorkerGlobalScope, MessageEvents, ErrorEvent } from '@ohos.worker'; let workerPort: ThreadWorkerGlobalScope = worker.workerPort; // 定義訓練模型及結果 let result; // 定義預測函式 function predict(x) { return result[x]; } // 定義最佳化器訓練過程 function optimize() { result = {}; } // Worker執行緒的onmessage邏輯 workerPort.onmessage = function (e: MessageEvents) { let data = e.data // 根據傳輸的資料的type選擇進行操作 switch (data.type) { case 0: // 進行訓練 optimize(); // 訓練之後傳送主執行緒訓練成功的訊息 workerPort.postMessage({ type: 'message', value: 'train success.' }); break; case 1: // 執行預測 const output = predict(data.value); // 傳送主執行緒預測的結果 workerPort.postMessage({ type: 'predict', value: output }); break; default: workerPort.postMessage({ type: 'message', value: 'send message is invalid' }); break; } }
6. 在Worker執行緒中完成任務之後,執行Worker執行緒銷燬操作。銷燬執行緒的方式主要有兩種:根據需要可以在宿主執行緒中對Worker執行緒進行銷燬;也可以在Worker執行緒中主動銷燬Worker執行緒。
在宿主執行緒中透過呼叫 onexit() 方法定義Worker執行緒銷燬後的處理邏輯。
// Worker執行緒銷燬後,執行onexit回撥方法 workerInstance.onexit = function() { console.info("main thread terminate"); }
方式一:在宿主執行緒中透過呼叫 terminate() 方法銷燬Worker執行緒,並終止Worker接收訊息。
// 銷燬Worker執行緒 workerInstance.terminate();
方式二:在Worker執行緒中透過呼叫 close() 方法主動銷燬Worker執行緒,並終止Worker接收訊息。
// 銷燬執行緒 workerPort.close();
二、I/O密集型任務開發指導
使用非同步併發可以解決單次I/O任務阻塞的問題,但是如果遇到I/O密集型任務,同樣會阻塞執行緒中其它任務的執行,這時需要使用多執行緒併發能力來進行解決。
I/O密集型任務的效能重點通常不在於CPU的處理能力,而在於I/O操作的速度和效率。這種任務通常需要頻繁地進行磁碟讀寫、網路通訊等操作。此處以頻繁讀寫系統檔案來模擬I/O密集型併發任務的處理。
1. 定義併發函式,內部密集呼叫I/O能力。
import fs from '@ohos.file.fs'; // 定義併發函式,內部密集呼叫I/O能力 @Concurrent async function concurrentTest(fileList: string[]) { // 寫入檔案的實現 async function write(data, filePath) { let file = await fs.open(filePath, fs.OpenMode.READ_WRITE); await fs.write(file.fd, data); fs.close(file); } // 迴圈寫檔案操作 for (let i = 0; i < fileList.length; i++) { write('Hello World!', fileList[i]).then(() => { console.info(`Succeeded in writing the file. FileList: ${fileList[i]}`); }).catch((err) => { console.error(`Failed to write the file. Code is ${err.code}, message is ${err.message}`) return false; }) } return true; }
2. 使用TaskPool執行包含密集I/O的併發函式:透過呼叫 execute() 方法執行任務,並在回撥中進行排程結果處理。示例中的filePath1和filePath2的獲取方式請參見 獲取應用檔案路徑 。
import taskpool from '@ohos.taskpool'; let filePath1 = ...; // 應用檔案路徑 let filePath2 = ...; // 使用TaskPool執行包含密集I/O的併發函式 // 陣列較大時,I/O密集型任務任務分發也會搶佔主執行緒,需要使用多執行緒能力 taskpool.execute(concurrentTest, [filePath1, filePath2]).then((ret) => { // 排程結果處理 console.info(`The result: ${ret}`); })
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70009402/viewspace-2986079/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- CPU-bound(計算密集型) 和I/O bound(I/O密集型)
- HarmonyOS電話服務開發指導
- HarmonyOS 裝置管理開發:USB 服務開發指導
- HarmonyOS:NativeWindow 開發指導
- HarmonyOS 應用事件打點開發指導事件
- 鴻蒙程式設計江湖:I/O 密集型任務處理及 ArkTS 的非同步鎖機制鴻蒙程式設計非同步
- HarmonyOS 後臺任務管理開發指南上線!
- 使用 setTimeout 拆解一些 CPU 密集型的執行任務
- HarmonyOS Next後臺任務開發入門:背景與基本任務型別型別
- HarmonyOS音訊開發指導:使用OpenSL ES開發音訊播放功能音訊
- 使用Rustlang的Async Tokio執行時處理CPU密集型任務Rust
- HarmonyOS音訊開發指導:使用AudioRenderer開發音訊播放功能音訊
- HarmonyOS:Neural Network Runtime 對接 AI 推理框架開發指導AI框架
- 計算機I/O與I/O模型計算機模型
- [轉載]iOS 後臺任務設計指導iOS
- HarmonyOS 位置服務開發指南
- Python教程:精簡概述I/O模型與I/O操作Python模型
- I/O阻塞與同步理解
- Android開發 - Runnable 類任務介面定義與後臺任務待辦解析Android
- Veritas Quick I/O and Cached Quick I/OUI
- Nagios外掛開發指導iOS
- Web開發的入門指導Web
- 任務佇列,巨集任務與微任務佇列
- 系統服務監控指標--load、CPU利用率、磁碟剩餘空間、磁碟I/O、記憶體使用情況等指標記憶體
- Linux下的5種I/O模型與3組I/O複用Linux模型
- 任務預測指標整理指標
- I/O埠和I/O記憶體記憶體
- 蛻變成蝶:Linux裝置驅動之CPU與記憶體和I/OLinux記憶體
- HarmonyOS UI 開發UI
- 《專案經理指導手冊》規範篇5,任務規範
- ? 前端開發行為指導規範前端
- java web開發之上機指導(2)JavaWeb
- scrum|敏捷開發之任務看板Scrum敏捷
- Native API 在 HarmonyOS 應用工程中的使用指導API
- JavaScript的巨集任務與微任務JavaScript
- Java I/OJava
- 敏捷開發-任務拆解、工作量評估和任務指派敏捷
- linux檢視 CPU,記憶體,網路流量和磁碟 I/OLinux記憶體