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