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