【鸿蒙实战开发】基于Taskpool的多线程操作

238 篇文章 0 订阅
200 篇文章 0 订阅

往期知识点整理

场景描述

场景一:周期性任务处理,业务通过taskpool周期性处理业务。
场景二:延迟业务处理,业务一段时间后,通过taskpool处理业务。
场景三:串行业务处理,业务开展过程中,需要处理一系列的事务,事务处理过程中,存在先后次序。
场景四:业务的处理存在紧急优先次序,支持设置taskpool优先级处理。
场景五:ArkTS与Native协作开展业务,在ArkTS层触发业务,通过NAPI接口,传递到Native C++层,作业务管理等处理。

方案描述

场景一:周期性任务

方案:

1)定时器判断周期性事务执行。

2)Taskpool来处理任务执行。

核心代码:

@Concurrent

function ServiceHandle(pars: number): number {

  hilog.info(0x0000, 'testTag', 'start ServiceHandle:%{public}d', pars);

  // 业务处理过程,并将结果返回

  let result = 0;

  return result;

}

let count = 0;

function TimerOutHandle(pars:number)

{

  count++;

  let task: taskpool.Task = new taskpool.Task(ServiceHandle, pars);

  hilog.info(0x0000, 'testTag', 'Timer handle count :%{public}d,pars %{public}d', count, pars);

  taskpool.execute(task, taskpool.Priority.HIGH).then((res: object) => {

    hilog.info(0x0000, 'testTag', 'ServiceHandle result :%{public}d', res);

    if (g_callback != null) {

      g_callback(count);

    }

  });

}

let timerId = -1;

export function TimerTest()

{

  count = 0;

  let value = 88;

  timerId = setInterval(TimerOutHandle, 3000, value);

}

定时器每3秒超时一次,进入TimerOutHandle函数处理,TimerOutHandle函数体中,通过taskpool创建异步并发任务执行业务。

运行结果:

界面上,每超时一次,会呈现运行次数:

场景二:延迟任务

方案:

1)通过setTimeout来延迟处理。

2) 通过executeDelayed来延迟处理。

核心代码:

1)setTimeout的处理如下:

@Concurrent

function ServiceHandle(pars: number): number {

  hilog.info(0x0000, 'testTag', 'start ServiceHandle:%{public}d', pars);

  // 业务处理过程,并将结果返回

  let result = 0;

  return result;

}

let count = 0;

function TimerOutHandle(pars:number)

{

  count++;

  let task: taskpool.Task = new taskpool.Task(ServiceHandle, pars);

  hilog.info(0x0000, 'testTag', 'Timer handle count :%{public}d,pars %{public}d', count, pars);

  taskpool.execute(task, taskpool.Priority.HIGH).then((res: object) => {

    hilog.info(0x0000, 'testTag', 'ServiceHandle result :%{public}d', res);

    if (g_callback != null) {

      g_callback(count);

    }

  });

}

export function OneTimerCallTest()

{

  count = 0;

  if (g_callback != null) {

    g_callback(count);

  }

  let value = 99;

  hilog.info(0x0000, 'testTag', 'start setTimeout');

  timerId = setTimeout(TimerOutHandle, 3000, value);

}

定时器3秒超时(仅仅执行一次)后,就会进入TimerOutHandle函数处理,TimerOutHandle函数体中,通过taskpool创建异步并发任务执行业务。

2)executeDelayed来延迟

@Concurrent

function TaskDelayServiceHandle(pars: number): number {

  let t: number = Date.now();

  hilog.info(0x0000, 'testTag', 'enter TaskDelayServiceHandle, timer is :%{public}d', t);

  // 业务处理过程,并将结果返回

  let result = 0;

  return result;

}

export function TaskPoolDelayTest()

{

  count = 0;

  if (g_callback != null) {

    g_callback(count);

  }

  let value = 100;

  let t: number = Date.now();

  hilog.info(0x0000, 'testTag', 'taskpool start time is :%{public}d', t);

  let task: taskpool.Task = new taskpool.Task(TaskDelayServiceHandle, value);

  taskpool.executeDelayed(3000, task).then(() => {

    count++;

    let t: number = Date.now();

    hilog.info(0x0000, 'testTag', 'taskpool execute success, time is :%{public}d', t);

    if (g_callback != null) {

      g_callback(count);

    }

  }).catch((e: BusinessError) => {

    console.error(`taskpool execute: Code: ${e.code}, message: ${e.message}`);

  })

}

调用executeDelayed函数3秒后,会进入TaskDelayServiceHandle函数执行,返回返回后,会进入executeDelayed后面的then的函数体中执行。

运行结果:

1)使用setTimeout运行结果

2)使用executeDelayed运行结果

场景三:串行任务

方案:

1)最简单的方案就是后面任务执行时,根据前面任务的执行结果来处理。

2)后面任务的执行,依赖另一个任务的一些处理结果后,继续执行。

核心代码:

1)通过业务逻辑的结果来处理

@Concurrent

function ServiceHandle1(pars: number): number {

  hilog.info(0x0000, 'testTag', 'start ServiceHandle1:%{public}d', pars);

  // 业务处理过程,并将结果返回

  let result = 0;

  return result;

}

@Concurrent

function ServiceHandle2(pars: number): number {

  hilog.info(0x0000, 'testTag', 'start ServiceHandle2:%{public}d', pars);

  // 业务处理过程,并将结果返回

  let result = 1;

  return result;

}

export function SyncHandle()

{

  let task1: taskpool.Task = new taskpool.Task(ServiceHandle1, 1);

  hilog.info(0x0000, 'testTag', 'sync handle');

  taskpool.execute(task1, taskpool.Priority.HIGH).then((res1: object) => {

    hilog.info(0x0000, 'testTag', 'ServiceHandle result :%{public}d', res1);

    if (g_callback != null) {

      g_callback('task1 finish.');

    }

    if ((res1 as Number) == 0) {

      let task2: taskpool.Task = new taskpool.Task(ServiceHandle2, 2);

      taskpool.execute(task2, taskpool.Priority.HIGH).then((res2: object) => {

        hilog.info(0x0000, 'testTag', 'ServiceHandle2 result :%{public}d', res2);

        if (g_callback != null) {

          g_callback('task2 finish.');

        }

      });

    }

  });

}

task1执行完毕后,根据if判断启动task2任务执行。

2)通过addDependency或SequenceRunner处理。

@Concurrent

function DependencyHandle(args: number): number {

  let t: number = Date.now();

  while ((Date.now() - t) < 1000) {

    continue;

  }

  return args;

}

export function AddDependencyTest()

{

  let task1:taskpool.Task = new taskpool.Task(DependencyHandle, 100);

  let task2:taskpool.Task = new taskpool.Task(DependencyHandle, 200);

  let task3:taskpool.Task = new taskpool.Task(DependencyHandle, 300);

  hilog.info(0x0000, 'testTag', 'dependency: add dependency start');

  task1.addDependency(task2);

  task2.addDependency(task3);

  hilog.info(0x0000, 'testTag', 'dependency: add dependency end');

  hilog.info(0x0000, 'testTag', 'dependency: start execute second');

  taskpool.execute(task1).then(() => {

    hilog.info(0x0000, 'testTag', 'dependency: first task1 success');

    if (g_callback != null) {

      g_callback('task1 finish.');

    }

  })

  taskpool.execute(task2).then(() => {

    hilog.info(0x0000, 'testTag', 'dependency: second task2 success');

    if (g_callback != null) {

      g_callback('task2 finish.');

    }

  })

  taskpool.execute(task3).then(() => {

    hilog.info(0x0000, 'testTag', 'dependency: third task3 success');

    if (g_callback != null) {

      g_callback('task3 finish.');

    }

  })

}

task1依赖task2,task2依赖task3,上面任务执行的顺序是:task3执行完毕后再执行task2,最后执行task。

@Concurrent

function additionDelay(delay:number): void {

  let start: number = new Date().getTime();

  while (new Date().getTime() - start < delay) {

    continue;

  }

}

@Concurrent

function waitForRunner(finalString: string): string {

  return finalString;

}

export async function SeqRunnerTest()

{

  let finalString:string = "";

  let task1:taskpool.Task = new taskpool.Task(additionDelay, 3000);

  let task2:taskpool.Task = new taskpool.Task(additionDelay, 2000);

  let task3:taskpool.Task = new taskpool.Task(additionDelay, 1000);

  let task4:taskpool.Task = new taskpool.Task(waitForRunner, finalString);

  let runner:taskpool.SequenceRunner = new taskpool.SequenceRunner();

  runner.execute(task1).then(() => {

    finalString += 'task1 finish.';

    hilog.info(0x0000, 'testTag', 'seqrunner: task1 done.');

    if (g_callback != null) {

      g_callback('task1 finish.');

    }

  });

  runner.execute(task2).then(() => {

    finalString += 'task2 finish.';

    hilog.info(0x0000, 'testTag', 'seqrunner: task2 done.');

    if (g_callback != null) {

      g_callback('task2 finish.');

    }

  });

  runner.execute(task3).then(() => {

    finalString += 'task3 finish.';

    hilog.info(0x0000, 'testTag', 'seqrunner: task3 done.');

    if (g_callback != null) {

      g_callback('task3 finish.');

    }

  });

  await runner.execute(task4);

  hilog.info(0x0000, 'testTag', 'seqrunner: task4 done, finalString is %{public}s', finalString);

}

task1执行完毕后,执行task2,最后是task3执行完毕。

运行结果:

1)通过业务逻辑的结果来处理

2)通过addDependency或SequenceRunner处理

场景四:优先级任务

方案:

在taskpool.execute的参数二种设置线程的优先级,优先级分三个级别:LOW、MEDIUM(默认)、HIGH。通过设置优先级来运行taskpool任务。

核心代码:

@Concurrent

function ServiceHandle(pri: string): string {

  hilog.info(0x0000, 'testTag', 'enter ServiceHandle:%{public}s', pri);

  hilog.info(0x0000, 'testTag', 'end ServiceHandle:%{public}s', pri);

  return pri;

}

export function CallPriorityHanel()

{

  let task1: taskpool.Task = new taskpool.Task(ServiceHandle, "LOW");

  let task2: taskpool.Task = new taskpool.Task(ServiceHandle, "MEDIUM");

  let task3: taskpool.Task = new taskpool.Task(ServiceHandle, "HIGH");

  taskpool.execute(task1, taskpool.Priority.LOW).then((res: object) => {

    hilog.info(0x0000, 'testTag', 'task return result :%{public}s', res);

  });

  taskpool.execute(task2, taskpool.Priority.MEDIUM).then((res: object) => {

    hilog.info(0x0000, 'testTag', 'task return result :%{public}s', res);

  });

  taskpool.execute(task3, taskpool.Priority.HIGH).then((res: object) => {

    hilog.info(0x0000, 'testTag', 'task return result :%{public}s', res);

  });

}

当前的设备都是多核的,并不是说将优先级设置程HIGH,该任务就会最先调度。

运行结果:

场景五:taskpool的Napi调用

方案:C++层编译的库,在ArkTS层通过import库的方式引用后,在taskpool的回调函数中调用接口。核心代码:

@Concurrent

function ServiceHandle(pars: number): number {

  hilog.info(0x0000, 'testTag', 'start ServiceHandle:%{public}d', pars);

  // 业务处理过程,并将结果返回

  testNapi.jsServiceHandle(88, 99);

  return 0;

}

export function CallHandle()

{

  let task: taskpool.Task = new taskpool.Task(ServiceHandle, 1);

  taskpool.execute(task,).then((res: object) => {

    hilog.info(0x0000, 'testTag', 'printArgs result :%{public}d', res);

  });

}

typedef struct TestData {

  int data;

  int type;

} TestData;

static napi_value JsServiceHandle(napi_env env, napi_callback_info info)

{

  size_t argc = 2;

  napi_value args[2] = {nullptr};

  napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

  TestData testData;

  napi_get_value_int32(env, args[0], &testData.data);

  napi_get_value_int32(env, args[1], &testData.type);

  OH_LOG_INFO(LOG_APP, "Native C++ Service handle:%{public}d,type:%{public}d", testData.data, testData.type);

  return nullptr;

}

EXTERN_C_START

static napi_value Init(napi_env env, napi_value exports)

{

  napi_property_descriptor desc[] = {

  {"jsServiceHandle", nullptr, JsServiceHandle, nullptr, nullptr, nullptr, napi_default, nullptr}

};

napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);

return exports;

}

EXTERN_C_END

运行结果:

总是有很多小伙伴反馈说:OpenHarmony开发不知道学习哪些技术?不知道需要重点掌握哪些OpenHarmony开发知识点? 为了解决大家这些学习烦恼。在这准备了一份很实用的鸿蒙全栈开发学习路线与学习文档给大家用来跟着学习。

针对一些列因素,整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线,包含了鸿蒙开发必掌握的核心知识要点,内容有(OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开发、系统定制移植……等)技术知识点。

《鸿蒙 (Harmony OS)开发学习手册》(共计892页):https://gitcode.com/HarmonyOS_MN/733GH/overview

如何快速入门?

1.基本概念
2.构建第一个ArkTS应用
3.……

开发基础知识:

1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……

在这里插入图片描述

基于ArkTS 开发

1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……

在这里插入图片描述

鸿蒙开发面试真题(含参考答案):https://gitcode.com/HarmonyOS_MN/733GH/overview

在这里插入图片描述

OpenHarmony 开发环境搭建

图片

《OpenHarmony源码解析》:https://gitcode.com/HarmonyOS_MN/733GH/overview

  • 搭建开发环境
  • Windows 开发环境的搭建
  • Ubuntu 开发环境搭建
  • Linux 与 Windows 之间的文件共享
  • ……
  • 系统架构分析
  • 构建子系统
  • 启动流程
  • 子系统
  • 分布式任务调度子系统
  • 分布式通信子系统
  • 驱动子系统
  • ……

图片

OpenHarmony 设备开发学习手册:https://gitcode.com/HarmonyOS_MN/733GH/overview

图片

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值