【HarmonyOS Next】【性能优化】多线程能力场景化示例实践

HarmonyOS Next应用开发案例(持续更新中……)
HarmonyOS Next性能指导总览

本篇文章链接,请访问:https://gitee.com/harmonyos-cases/cases/blob/master/docs/performance/multi_thread_capability.md

简介

应用中的每个进程都会有一个主线程,主线程主要承担执行UI绘制操作、管理ArkTS引擎实例的创建和销毁、分发和处理事件、管理Ability生命周期等职责,具体可参见线程模型概述。因此,开发应用时应当尽量避免将耗时的操作放在主线程中执行。ArkTS提供了WorkerTaskPool两种多线程并发能力,多线程并发允许在同一时间段内同时执行多段代码,这两个并发的基本能力可参见TaskPool和Worker的对比

在介绍WorkerTaskPool的详细使用方法前,我们先简单介绍并发模型的相关概念,以便于大家的理解。

并发模型概述

并发的意思是多个任务同时执行。并发模型分为两大类:基于内存共享的并发模型和基于消息传递的并发模型。

在基于内存共享的并发模型中,并发线程通过读写内存中的共享对象来进行交互。基于共享内存的并发编程需要满足三条性质:

  • 原子性:指一个操作是不可中断的,要么全部执行成功要么全部执行失败。

  • 有序性:指程序执行的顺序必须符合预期,不能出现乱序的情况。

  • 可见性:指当一个线程修改了共享变量后,其他线程能够立即得知这个修改。

现代程序语言一般通过锁、内存屏障、原子指令来满足这三条性质。基于内存共享的并发模型与底层硬件接近,在能正确撰写并发代码的情况下,可以最大发挥底层硬件性能,实现性能优秀的多线程程序。但是这种并发模型难以掌握,即使资深的程序员也非常容易犯错。典型的基于内存共享并发模型的程序语言有C++ 、Swift和Java等。

在基于消息传递的并发模型中,并发线程的内存相互隔离,需要通过通信通道相互发送消息来进行交互。典型的基于消息传递的并发模型一般有两种:CSP和Actor。

CSP(Communicating Sequential Processes,通信顺序进程)中的计算单元并不能直接互相发送信息。需要通过通道(Channel)作为媒介进行消息传递:发送方需要将消息发送到Channel,而接收方需要从Channel读取消息。与CSP不同,在Actor模型中,每个Actor可以看做一个独立的计算单元,并且相互之间内存隔离,每个Actor中存在信箱(Mail Box),Actor之间可以直接进行消息传递,如下图所示:

图1 Actor消息传递示意图

CSP与Actor之间的主要区别:

  • Actor需要明确指定消息接收方,而CSP中处理单元不用关心这些,只需要把消息发送给Channel,而接收方只需要从Channel读取消息。

  • 由于在默认情况下Channel是没有缓存的,因此对Channel的发送(Send)动作是同步阻塞的,直到另外一个持有该Channel引用的执行块取出消息,而Actor模型中信箱本质是队列,因此消息的发送和接收可以是异步的。

典型的基于消息传递的并发模型的程序语言有:Dart、JS和ArkTS。当前系统中Worker和TaskPool都是基于Actor并发模型实现的并发能力。

Worker

基本概念和运作原理

当前系统中的Worker是一个独立的线程,基本概念可参见TaskPool和Worker的对比。Worker拥有独立的运行环境,每个Worker线程和主线程一样拥有自己的内存空间、消息队列(MessageQueue)、事件轮询机制(EventLoop)、调用栈(CallStack)等。线程之间通过消息(Massage)进行交互,如下图所示:

图2 线程交互示意图

在多核的情况下(下图中的CPU 1和CPU 2同时工作),多个Worker线程(下图中的worker thread1和worker thread2)可以同时执行,因此Worker线程做到了真正的并发,如下图所示:

图3 Worker线程并发示意图

使用场景和开发示例

对于Worker,有以下适用场景:

  • 运行时间超过3分钟的任务,需要使用Worker。

  • 有关联的一系列同步任务,例如数据库增、删、改、查等,要保证同一个句柄,需要使用Worker。

以视频解压的场景为例,点击右上角下载按钮,该示例会执行网络下载并监听,下载完成后自动执行解压操作。当视频过大时,可能会出现解压时长超过3分钟耗时的情况,因此我们选用该场景来说明如何使用Worker。

场景预览图如下所示:

图4 场景预览图

使用步骤如下:

  1. 宿主线程创建一个Worker线程。通过new worker.ThreadWorker()创建Worker实例,示例代码如下:

    // 引入worker模块
    import worker, { MessageEvents } from '@ohos.worker';
    import type common from '@ohos.app.ability.common';
            
    let wo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值