衡阳派盒市场营销有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

HarmonyOS CPU與I/O密集型任務開發指導

王程 ? 來源:jf_75796907 ? 作者:jf_75796907 ? 2024-02-18 10:17 ? 次閱讀

一、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”。

wKgaomXPT9aAPY5fAAIhtawiAa0789.pngwKgZomXPT8SATNG3AAIhtawiAa0161.png

? 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}`);
})


審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • cpu
    cpu
    +關注

    關注

    68

    文章

    10904

    瀏覽量

    213023
  • 圖像處理
    +關注

    關注

    27

    文章

    1300

    瀏覽量

    56894
  • 線程
    +關注

    關注

    0

    文章

    505

    瀏覽量

    19758
  • HarmonyOS
    +關注

    關注

    79

    文章

    1982

    瀏覽量

    30579
收藏 人收藏

    評論

    相關推薦

    鴻蒙OS開發實例:【ArkTS類庫多線程CPU密集型任務TaskPool】

    CPU密集型任務是指需要占用系統資源處理大量計算能力的任務,需要長時間運行,這段時間會阻塞線程其它事件的處理,不適宜放在主線程進行。例如圖像處理、視頻編碼、數據分析等。 基于多線
    的頭像 發表于 04-01 22:25 ?901次閱讀
    鴻蒙OS<b class='flag-5'>開發</b>實例:【ArkTS類庫多線程<b class='flag-5'>CPU</b><b class='flag-5'>密集型</b><b class='flag-5'>任務</b>TaskPool】

    鴻蒙原生應用開發-ArkTS語言基礎類庫多線程CPU密集型任務TaskPool

    CPU密集型任務是指需要占用系統資源處理大量計算能力的任務,需要長時間運行,這段時間會阻塞線程其它事件的處理,不適宜放在主線程進行。例如圖像處理、視頻編碼、數據分析等。 基于多線程并發
    發表于 03-19 14:14

    鴻蒙原生應用開發-ArkTS語言基礎類庫多線程I/O密集型任務開發

    使用異步并發可以解決單次I/O任務阻塞的問題,但是如果遇到I/O密集型
    發表于 03-21 14:57

    計算密集型的程序簡析

    人工智能學習1. 人工智能應用場景網絡安全、電子商務、計算模擬、社交網絡 … …2. 人工智能必備三要素數據,算法,計算力計算力之CPU、GPU對比:CPU主要適合I\O
    發表于 09-07 06:14

    HarmonyOS如何使用異步并發能力進行開發

    UI的同時,后臺也能執行耗時操作,從而避免應用出現卡頓。 并發能力在多種場景中都有應用,其中包括單次I/O任務CPU密集型
    發表于 09-22 17:35

    HarmonyOS CPUI/O密集型任務開發指導

    workerPort.close(); 二、I/O密集型任務開發指導 使用異步并發可以解決單次I
    發表于 09-26 16:29

    HarmonyOS語言基礎類庫開發指南上線啦!

    /cpu-intensive-task-development-0000001681369757-V3?? **I/O密集型任務
    發表于 10-18 16:36

    ZigBee2007視頻教程-應用開發指導

    ZigBee2007視頻教程-應用開發指導ZigBee2007視頻教程-應用開發指導ZigBee2007視頻教程-應用開發指導ZigBee2007視頻教程-應用開發指導
    發表于 12-29 10:31 ?19次下載

    I/O密集型虛擬機的域間通信優化方法

    I/O密集型虛擬機需要頻繁地進行域間通信,為解決現有虛擬機域間通信效率低、延遲大的問題,提出一種基于雙環形緩沖區的用戶域與驅動域域間通信優化方法。在用戶域中建立與驅動域共享的雙環形緩沖區,由虛擬機
    發表于 03-01 15:42 ?0次下載
    <b class='flag-5'>I</b>/<b class='flag-5'>O</b><b class='flag-5'>密集型</b>虛擬機的域間通信優化方法

    FPGA執行計算密集型任務性能表現及優勢有哪些

    FPGA可用于處理多元計算密集型任務,依托流水線并行結構體系,FPGA相對GPU、CPU在計算結果返回時延方面具備技術優勢。
    的頭像 發表于 11-10 09:49 ?1024次閱讀

    云優化性能:使用基于閃存的存儲的I/O密集型工作負載

    電子發燒友網站提供《云優化性能:使用基于閃存的存儲的I/O密集型工作負載.pdf》資料免費下載
    發表于 08-28 10:04 ?0次下載
    云優化性能:使用基于閃存的存儲的<b class='flag-5'>I</b>/<b class='flag-5'>O</b><b class='flag-5'>密集型</b>工作負載

    HarmonyOS語言基礎類庫開發指南上線啦!

    南中提供了詳細的介紹和開發指導,幫助開發者全面了解并發實現、容器類庫基礎操作、XML的生成解析與轉換等。 本期HarmonyOS開發者資料直通車帶您快速了解內容干貨~ 一 語言基礎類庫
    的頭像 發表于 10-18 16:20 ?630次閱讀
    <b class='flag-5'>HarmonyOS</b>語言基礎類庫<b class='flag-5'>開發指</b>南上線啦!

    HarmonyOS后臺任務管理開發指南上線!

    為什么要使用后臺任務開發過程中如何選擇合適的后臺任務?后臺任務申請時存在哪些約束與限制? 針對開發者使用后臺
    的頭像 發表于 11-28 21:10 ?817次閱讀
    <b class='flag-5'>HarmonyOS</b>后臺<b class='flag-5'>任務</b>管理<b class='flag-5'>開發指</b>南上線!

    鴻蒙OS開發實例:【ArkTS類庫多線程I/O密集型任務開發

    使用異步并發可以解決單次I/O任務阻塞的問題,但是如果遇到I/O密集型
    的頭像 發表于 04-01 16:32 ?585次閱讀
    鴻蒙OS<b class='flag-5'>開發</b>實例:【ArkTS類庫多線程<b class='flag-5'>I</b>/<b class='flag-5'>O</b><b class='flag-5'>密集型</b><b class='flag-5'>任務</b><b class='flag-5'>開發</b>】

    怎么在JAVA中確定線性池大小

    在JAVA中確定線性池大小,分別介紹CPU密集型任務I/O密集型
    的頭像 發表于 10-24 14:02 ?235次閱讀
    百家乐官网家乐娱乐城| 松溪县| 真人百家乐破解软件下载| 网络百家乐官网棋牌| 六合彩开奖号码| 缅甸百家乐赌城| 百家乐官网园首选海立方| 百家乐官网实时路单| 大发888游戏币| 百家乐最低投注| 百家乐官网顶尖高手| 讷河市| 大发888官方网站指定开| 单机百家乐官网的玩法技巧和规则| 百家乐官网路纸表格| 手机棋牌游戏平台| 欢乐谷百家乐的玩法技巧和规则| 做生意门面对着什么方向好| 真人百家乐官网代理分成| 钦州市| 大发888无数| 百家乐tt赌场娱乐网规则| 百家乐官网注码论坛| 大发888娱乐| 大发888充值100元| 百家乐押注方法| 网上百家乐靠谱吗| 曲松县| 六合彩开奖| 大发888游戏平台dafa888gw | 功夫百家乐官网的玩法技巧和规则| 百家乐官网为什么庄5| 瑞博网站| 澳门顶级赌场手机版| A8百家乐的玩法技巧和规则| 百家乐输了100万| 888百家乐官网的玩法技巧和规则| 百家乐官网AG| 菲律宾百家乐官网游戏| 博彩娱乐| 凯旋门娱乐城开户网址|