HarmonyOS应用开发实战:ArkTS语言踩坑解决方案

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值