W3Cschool
恭喜您成為首批注冊用戶
獲得88經驗值獎勵
TaskPool(任務池)和Worker的作用是為應用程序提供一個多線程的運行環(huán)境,用于處理耗時的計算任務或其他密集型任務。可以有效地避免這些任務阻塞主線程,從而最大化系統(tǒng)的利用率,降低整體資源消耗,并提高系統(tǒng)的整體性能。
本文將從實現(xiàn)特點和適用場景兩個方面來進行TaskPool與Worker的比較,同時提供了各自運作機制和注意事項的相關說明。
表1 TaskPool和Worker的實現(xiàn)特點對比
實現(xiàn) | TaskPool | Worker |
---|---|---|
內存模型 | 線程間隔離,內存不共享。 | 線程間隔離,內存不共享。 |
參數(shù)傳遞機制 | 采用標準的結構化克隆算法(Structured Clone)進行序列化、反序列化,完成參數(shù)傳遞。 支持ArrayBuffer轉移和SharedArrayBuffer共享。 | 采用標準的結構化克隆算法(Structured Clone)進行序列化、反序列化,完成參數(shù)傳遞。 支持ArrayBuffer轉移和SharedArrayBuffer共享。 |
參數(shù)傳遞 | 直接傳遞,無需封裝,默認進行transfer。 | 消息對象唯一參數(shù),需要自己封裝。 |
方法調用 | 直接將方法傳入調用。 | 在Worker線程中進行消息解析并調用對應方法。 |
返回值 | 異步調用后默認返回。 | 主動發(fā)送消息,需在onmessage解析賦值。 |
生命周期 | TaskPool自行管理生命周期,無需關心任務負載高低。 | 開發(fā)者自行管理Worker的數(shù)量及生命周期。 |
任務池個數(shù)上限 | 自動管理,無需配置。 | 同個進程下,最多支持同時開啟8個Worker線程。 |
任務執(zhí)行時長上限 | 無限制。 | 無限制。 |
設置任務的優(yōu)先級 | 不支持。 | 不支持。 |
執(zhí)行任務的取消 | 支持取消任務隊列中等待的任務。 | 不支持。 |
TaskPool偏向獨立任務維度,該任務在線程中執(zhí)行,無需關注線程的生命周期,超長任務(大于3分鐘)會被系統(tǒng)自動回收;而Worker偏向線程的維度,支持長時間占據(jù)線程執(zhí)行,需要主動管理線程生命周期。
常見的一些開發(fā)場景及適用具體說明如下:
TaskPool支持開發(fā)者在主線程封裝任務拋給任務隊列,系統(tǒng)選擇合適的工作線程,進行任務的分發(fā)及執(zhí)行,再將結果返回給主線程。接口直觀易用,支持任務的執(zhí)行、取消。工作線程數(shù)量上限為4。
圖2 Worker運作機制示意圖
創(chuàng)建Worker的線程稱為宿主線程(不一定是主線程,工作線程也支持創(chuàng)建Worker子線程),Worker自身的線程稱為Worker子線程(或Actor線程、工作線程)。每個Worker子線程與宿主線程擁有獨立的實例,包含基礎設施、對象、代碼段等。Worker子線程和宿主線程之間的通信是基于消息傳遞的,Worker通過序列化機制與宿主線程之間相互通信,完成命令及數(shù)據(jù)交互。
實現(xiàn)任務的函數(shù)需要使用裝飾器@Concurrent標注,且僅支持在.ets文件中使用。
實現(xiàn)任務的函數(shù)入?yún)⑿铦M足序列化支持的類型,詳情請參見數(shù)據(jù)傳輸對象。
由于不同線程中上下文對象是不同的,因此TaskPool工作線程只能使用線程安全的庫,例如UI相關的非線程安全庫不能使用。
序列化傳輸?shù)臄?shù)據(jù)量大小限制為16MB。
當使用Worker模塊具體功能時,均需先構造Worker實例對象,其構造函數(shù)與API版本相關。
- // 導入模塊
- import worker from '@ohos.worker';
- // API 9及之后版本使用:
- const worker1 = new worker.ThreadWorker(scriptURL);
- // API 8及之前版本使用:
- const worker1 = new worker.Worker(scriptURL);
構造函數(shù)需要傳入Worker的路徑(scriptURL),Worker文件存放位置默認路徑為Worker文件所在目錄與pages目錄屬于同級。
Stage模型
構造函數(shù)中的scriptURL示例如下:
- // 導入模塊
- import worker from '@ohos.worker';
- // 寫法一
- // Stage模型-目錄同級(entry模塊下,workers目錄與pages目錄同級)
- const worker1 = new worker.ThreadWorker('entry/ets/workers/MyWorker.ts', {name:"first worker in Stage model"});
- // Stage模型-目錄不同級(entry模塊下,workers目錄是pages目錄的子目錄)
- const worker2 = new worker.ThreadWorker('entry/ets/pages/workers/MyWorker.ts');
- // 寫法二
- // Stage模型-目錄同級(entry模塊下,workers目錄與pages目錄同級),假設bundlename是com.example.workerdemo
- const worker3 = new worker.ThreadWorker('@bundle:com.example.workerdemo/entry/ets/workers/worker');
- // Stage模型-目錄不同級(entry模塊下,workers目錄是pages目錄的子目錄),假設bundlename是com.example.workerdemo
- const worker4 = new worker.ThreadWorker('@bundle:com.example.workerdemo/entry/ets/pages/workers/worker');
基于Stage模型工程目錄結構,寫法一的路徑含義:
基于Stage模型工程目錄結構,寫法二的路徑含義:
FA模型
構造函數(shù)中的scriptURL示例如下:
- // 導入模塊
- import worker from '@ohos.worker';
- // FA模型-目錄同級(entry模塊下,workers目錄與pages目錄同級)
- const worker1 = new worker.ThreadWorker('workers/worker.js', {name:'first worker in FA model'});
- // FA模型-目錄不同級(entry模塊下,workers目錄與pages目錄的父目錄同級)
- const worker2 = new worker.ThreadWorker('../workers/worker.js');
Worker的創(chuàng)建和銷毀耗費性能,建議開發(fā)者合理管理已創(chuàng)建的Worker并重復使用。Worker空閑時也會一直運行,因此當不需要Worker時,可以調用terminate()接口或parentPort.close()方法主動銷毀Worker。若Worker處于已銷毀或正在銷毀等非運行狀態(tài)時,調用其功能接口,會拋出相應的錯誤。
Worker存在數(shù)量限制,支持最多同時存在8個Worker。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: