TaskPool、Worker和各个ArkTS引擎实例之间是否内存隔离
TaskPool和Worker基于Actor模型实现并发,Actor模型具备内存隔离的特性,所以TaskPool、Worker和各个ArkTS引擎实例之间是内存隔离的。
在TaskPool的生命周期中TaskPool线程什么时候会被销毁
TaskPool的生命周期无需开发者手动去管理。有一定时间没有执行新的任务,或者在TaskPool线程上没有执行监听任务的情况下,线程可能会被销毁。
TaskPool对于任务时间有没有限制
任务时常上限3分钟(不包含Promise和async/await异步调用的耗时)。
对于预加载任务量大的场景推荐使用Worker还是TaskPool
Worker存在数量限制,支持最多同时存在8个Worker。所以针对预加载任务量大的场景,推荐使用TaskPool。
存在线程复用的并发场景,推荐使用Worker还是TaskPool
同一个Worker无法执行不同的任务,所以针对线程复用的并发场景,推荐使用TaskPool。
是否可以在TaskPool中动态加载模块(Har、Hsp、So)?(API 10)
解决方案
可以,TaskPool动态加载能力跟主线程能力一致。但是TaskPool线程加载后,由于模块化线程隔离的缘故,不能给主线程复用。
如何实现多线程数据共享?(API 10)
原理澄清
由于ArkTS是单线程模型,内存隔离,因此大部分普通对象跨线程均采用序列化方式。
解决方案
目前部分支持共享的对象如下: 通过ArrayBuffer的转移传输和SharedArrayBuffer进行共享。
线程间JS对象的数据通信依赖序列化方式,是否存在性能问题?(API 10)
原理澄清
目前线程间对象的数据通信依赖序列化、反序列化,耗时与数据量相关,需要控制传输的数据量,或者采用ArrayBuffer或者SharedArrayBuffer的转移或者共享。
Worker可用线程数量少,无法满足应用平移适配需求,部分应用可能超过200个线程。 TaskPool和Worker都无法提供对等的线程数量,应该如何设计大量线程并发方案?(API 10)
解决方案
系统采用ArkTS作为开发语言,由于底层线程模型对接了libuv,因此在应用进程启动后,会有多个I/O线程用于I/O操作,JS线程的I/O异步操作,会在I/O线程执行,JS线程可以同时执行其他操作,不存在阻塞等待问题。 同时,ArkTS提供了TaskPool并发API,类似GCD的线程池能力,可以执行任务,而且不需要开发者进行线程生命周期管理。 因此针对需要大量线程的问题,开发建议如下: 将多线程任务转变为并发任务,通过TaskPool分发执行 I/O型任务不需要单独开启线程,而是在当前线程(可以是TaskPool线程)执行 少量需要常驻的CPU密集型任务,采用Worker,并且需要控制在8个及以下。
并发任务的调度及实时性问题,如何设置Task优先级,各个优先级的调度策略有什么区别,原理是什么,分别推荐在什么场景使用?(API 10)
解决方案
当前支持设置任务优先级,同一任务重复执行的顺序和优先级没关系,主要看任务执行的顺序,不同任务指定不同优先级示例如下:
代码示例
@Concurrent
function printArgs(args: number): number {
let t: number = Date.now();
while (Date.now() - t < 1000) { // 1000: delay 1s
continue;
}
console.info("printArgs: " + args);
return args;
}
let allCount = 100; // 100: test number
let taskArray: Array<taskpool.Task> = [];
// 创建300个任务并添加至taskArray
for (let i: number = 1; i < allCount; i++) {
let task1: taskpool.Task = new taskpool.Task(printArgs, i);
taskArray.push(task1);
let task2: taskpool.Task = new taskpool.Task(printArgs, i * 10); // 10: test number
taskArray.push(task2);
let task3: taskpool.Task = new taskpool.Task(printArgs, i * 100); // 100: test number
taskArray.push(task3);
}
// 从taskArray中获取不同的任务并给定不同优先级执行
for (let i: number = 0; i < allCount; i+=3) { // 3: 每次执行3个任务,循环取任务时需后移3项,确保执行的是不同的任务
taskpool.execute(taskArray[i], taskpool.Priority.HIGH);
taskpool.execute(taskArray[i + 1], taskpool.Priority.LOW);
taskpool.execute(taskArray[i + 2], taskpool.Priority.MEDIUM);
}
ts
如何将内存共享的线程模型,转换成在ArkTS的线程模型下(内存隔离)的实现方式?(API 11)
解决方案
可以利用TaskPool接口转换,大概可以分为如下五个场景。
场景一:主线程将独立的耗时任务放到子线程执行
代码示例:
共享内存写法
class Task {
static run(args) {
// Do some independent task
}
}
let thread = new Thread(() => {
let result = Task.run(args)
// deal with result
})
ts
ArkTS写法
im