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

101 篇文章 0 订阅
101 篇文章 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来延迟处理。

  1. 通过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

运行结果:

鸿蒙全栈开发全新学习指南

为了积极培养鸿蒙生态人才,让大家都能学习到鸿蒙开发最新的技术,针对一些在职人员、0基础小白、应届生/计算机专业、鸿蒙爱好者等人群,整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线【包含了大厂APP实战项目开发】

本路线共分为四个阶段

第一阶段:鸿蒙初中级开发必备技能

在这里插入图片描述

第二阶段:鸿蒙南北双向高工技能基础:gitee.com/MNxiaona/733GH

第三阶段:应用开发中高级就业技术

第四阶段:全网首发-工业级南向设备开发就业技术:gitee.com/MNxiaona/733GH

《鸿蒙 (Harmony OS)开发学习手册》(共计892页)

如何快速入门?

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

开发基础知识:gitee.com/MNxiaona/733GH

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.……

鸿蒙开发面试真题(含参考答案):gitee.com/MNxiaona/733GH

鸿蒙入门教学视频:

美团APP实战开发教学:gitee.com/MNxiaona/733GH

写在最后

  • 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
  • 想要获取更多完整鸿蒙最新学习资源,请移步前往小编:gitee.com/MNxiaona/733GH

  • 19
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值