使用Worker创建线程
基本概念 :Worker主要为应用程序提供多线程运行环境,可让应用程序在执行过程中与宿主线程分离,在后台线程中运行脚本进行耗时操作,避免计算密集型或高延迟任务阻塞宿主线程。使用方法 :
创建Worker线程文件 :Worker线程文件需要放在{moduleName}/src/main/ets/
目录层级之下。可以手动创建相关目录及文件,并配置build-profile.json5
的相关字段信息;也可以使用DevEco Studio一键生成Worker,自动生成模板文件及配置信息。构造Worker实例 :根据不同的API版本和模型,使用相应的构造函数传入Worker线程文件的路径来创建worker.ThreadWorker
或worker.Worker
实例。例如,在API 9及之后版本的Stage模型下,如果worker
线程文件所在路径为"entry/src/main/ets/workers/worker.ets"
,则可以这样创建:const workerStage1: worker.ThreadWorker = new worker.ThreadWorker('entry/ets/workers/worker.ets');
通信与任务执行 :在宿主线程和Worker子线程中通过onmessage
和postMessage
方法进行消息传递,以实现数据交互和任务执行。 注意事项 :
需要手动管理Worker的生命周期,且最多同时运行的Worker子线程数量为64个。当不需要Worker时,应调用terminate()
接口或close()
方法主动销毁Worker,避免资源浪费。 使用Worker模块时,需要在宿主线程中注册onerror
接口,否则当Worker线程出现异常时会发生jscrash
问题。 不支持跨HAP使用Worker线程文件,引用HAR/HSP前,需要先配置对HAR/HSP的依赖。
使用TaskPool创建线程
基本概念 :TaskPool为应用程序提供多线程运行环境,能降低资源消耗、提升系统性能,开发者无需关心线程实例的生命周期。它支持在宿主线程封装任务并抛给任务队列,系统会选择合适的工作线程进行任务分发与执行,并将结果返回给宿主线程。使用方法 :
定义任务函数 :使用@Concurrent
装饰器标注要在任务池中执行的函数。该装饰器从API version 9开始支持,仅在Stage模型的工程中的.ets
文件中使用。被装饰的函数可以是async
函数或普通函数,但禁止是generator
、箭头函数、类方法,也不支持类成员函数或者匿名函数。函数内允许使用local
变量、入参和通过import
引入的变量,禁止使用闭包变量。创建任务并执行 :在需要执行并发任务的地方,创建taskpool.Task
对象,将定义好的任务函数作为参数传入,并通过taskpool.execute
方法执行任务。例如:
import { taskpool } from '@kit.ArkTS' ;
@ Concurrent
function add ( num1: number , num2: number ) : number {
return num1 + num2;
}
async function ConcurrentFunc ( ) : Promise < void > {
try {
let task: taskpool. Task = new taskpool . Task ( add, 1 , 2 ) ;
console . info ( "taskpool res is: " + await taskpool. execute ( task) ) ;
} catch ( e) {
console . error ( "taskpool execute error is: " + e) ;
}
}
@ Entry
@ Component
struct Index {
@ State message: string = 'Hello World' ;
build ( ) {
Row ( ) {
Column ( ) {
Text ( this . message)
. fontSize ( 50 )
. fontWeight ( FontWeight. Bold)
. onClick ( ( ) => {
ConcurrentFunc ( ) ;
} )
}
. width ( '100%' )
}
. height ( '100%' )
}
}
注意事项 :
任务函数在TaskPool工作线程的执行耗时不能超过3分钟(不包含Promise
和async/await
异步调用的耗时,例如网络下载、文件读写等I/O任务的耗时),否则会被强制退出。 实现任务的函数入参需满足序列化支持的类型。ArrayBuffer
参数在TaskPool中默认转移,需要设置转移列表的话可通过接口setTransferList()
设置。 从API version 11开始,跨并发实例传递带方法的实例对象时,该类必须使用@Sendable
装饰器标注,且仅支持在.ets
文件中使用。
通过NAPI机制在C代码中使用标准线程API创建线程
基本概念 :通过NAPI(Native API)机制,可以在C代码中使用标准的线程API来创建线程,直接利用操作系统提供的线程创建和管理功能,实现更底层的线程控制。使用方法 :通常使用pthread_create
函数来创建线程,其函数原型为int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
。例如:
# include <pthread.h>
void * CreateArkRuntimeFunc ( void * arg) {
return NULL ;
}
int main ( ) {
pthread_t tid;
pthread_create ( & tid, nullptr, CreateArkRuntimeFunc, nullptr) ;
pthread_join ( tid, NULL ) ;
return 0 ;
}