DEV Community

SameX
SameX

Posted on

鸿蒙编程江湖:深入理解TaskPool和Worker的并发任务执行

本文旨在深入探讨华为鸿蒙HarmonyOS Next系统(截止目前API12)的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。

鸿蒙系统提供了两种并发能力:TaskPool 和 Worker。它们都基于 Actor 并发模型实现,但它们的使用场景和功能有所不同。

  • TaskPool:TaskPool 是一个多线程运行环境,它提供了任务的执行、取消、优先级设置等功能。TaskPool 适用于独立任务,例如计算密集型任务、I/O 密集型任务等。
  • Worker:Worker 是一个可以长时间运行的后台线程,它支持与宿主线程之间的消息传递。Worker 适用于长时间运行的任务,例如后台数据处理、模型训练等。 ### TaskPool 和 Worker 的区别与使用场景 | 特性 | TaskPool | Worker | |---|---|---| | 内存模型 | 线程间隔离,内存不共享 | 线程间隔离,内存不共享 | | 参数传递机制 | 采用标准的结构化克隆算法(Structured Clone)进行序列化、反序列化,完成参数传递。支持 ArrayBuffer 转移和 SharedArrayBuffer 共享。 | 采用标准的结构化克隆算法(Structured Clone)进行序列化、反序列化,完成参数传递。支持 ArrayBuffer 转移和 SharedArrayBuffer 共享。 | | 参数传递 | 直接传递,无需封装,默认进行 transfer。 | 消息对象唯一参数,需要自己封装。 | | 方法调用 | 直接将方法传入调用。 | 在 Worker 线程中进行消息解析并调用对应方法。 | | 返回值 | 异步调用后默认返回。 | 主动发送消息,需在 onmessage 解析赋值。 | | 生命周期 | TaskPool 自动管理生命周期,无需关心任务负载高低。 | 开发者自行管理 Worker 的数量及生命周期。 | | 任务池个数上限 | 自动管理,无需配置。 | 同个进程下,最多支持同时开启 64 个 Worker 线程,实际数量由进程内存决定。 | | 任务执行时长上限 | 3 分钟(不包含 Promise 和 async/await 异步调用的耗时,例如网络下载、文件读写等 I/O 任务的耗时),长时任务无执行时长上限。 | 无限制。 | | 设置任务的优先级 | 支持配置任务优先级。 | 不支持。 | | 执行任务的取消 | 支持取消已经发起的任务。 | 不支持。 | | 线程复用 | 支持。 | 不支持。 | | 任务延时执行 | 支持。 | 不支持。 | | 设置任务依赖关系 | 支持。 | 不支持。 | | 串行队列 | 支持。 | 不支持。 | | 任务组 | 支持。 | 不支持。 | 使用场景
  • TaskPool:适用于独立任务,例如计算密集型任务、I/O 密集型任务等。
  • Worker:适用于长时间运行的任务,例如后台数据处理、模型训练等。 ### TaskGroup 的管理与任务优先级 TaskGroup:TaskGroup 是一个任务集合,可以将多个任务添加到 TaskGroup 中,并一起执行。TaskGroup 支持配置任务的优先级。 示例
import { taskpool } from '@kit.ArkTS';
@Concurrent
function add(num1: number, num2: number): number {
  return num1 + num2;
}
@Concurrent
function subtract(num1: number, num2: number): number {
  return num1 - num2;
}
async function concurrentFunc() {
  const task1 = new taskpool.Task(add, 1, 2);
  const task2 = new taskpool.Task(subtract, 3, 4);
  const group = new taskpool.TaskGroup();
  group.addTask(task1);
  group.addTask(task2);
  group.addTask(task1); // 添加重复任务
  await taskpool.execute(group, taskpool.Priority.HIGH);
}
Enter fullscreen mode Exit fullscreen mode

任务优先级

  • Priority.IDLE:后台任务,优先级最低。
  • Priority.LOW:低优先级任务。
  • Priority.MEDIUM:中等优先级任务。
  • Priority.HIGH:高优先级任务。 ### 任务的添加与执行逻辑 任务添加
const task = new taskpool.Task(func, args);
Enter fullscreen mode Exit fullscreen mode

任务执行

await taskpool.execute(task);
Enter fullscreen mode Exit fullscreen mode

任务取消

taskpool.cancel(task);
Enter fullscreen mode Exit fullscreen mode

示例代码:通过 TaskPool 执行 CPU 密集型任务的示例

以下是一个简单的示例,演示如何使用 TaskPool 执行 CPU 密集型任务:

import { taskpool } from '@kit.ArkTS';
@Concurrent
function complexCalculation(data: ArrayBuffer): ArrayBuffer {
  // 执行复杂的计算操作
  return data;
}
async function concurrentCalculation() {
  const data = new ArrayBuffer(1024);
  const task = new taskpool.Task(complexCalculation, data);
  await taskpool.execute(task);
}
@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(async () => {
            await concurrentCalculation();
          })
          .width('100%');
      }
    }
    .height('100%');
  }
}
Enter fullscreen mode Exit fullscreen mode

这段代码定义了一个名为 Index 的组件,并在组件中显示了一条文本消息 "Hello World"。点击按钮会执行 concurrentCalculation 函数,该函数创建一个并发任务并执行它。任务完成后,会在控制台输出结果。

总结

通过以上介绍,您可以了解到鸿蒙系统中的 TaskPool 和 Worker 并发能力的使用方法。TaskPool 和 Worker 都是基于 Actor 并发模型实现的,但它们的使用场景和功能有所不同。希望本文能够帮助您掌握鸿蒙系统中的并发编程技术,并开发出更优秀的鸿蒙应用。

AWS GenAI LIVE image

How is generative AI increasing efficiency?

Join AWS GenAI LIVE! to find out how gen AI is reshaping productivity, streamlining processes, and driving innovation.

Learn more

Top comments (0)

AWS GenAI LIVE image

Real challenges. Real solutions. Real talk.

From technical discussions to philosophical debates, AWS and AWS Partners examine the impact and evolution of gen AI.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay