前言
2024年可谓至关重要,而生态建设的前提,就是要有足够的开发人才。与之对应的,今年春招市场上与鸿蒙相关岗位和人才旺盛的热度,一方面反应了鸿蒙生态的逐渐壮大,另一方面也让人们对鸿蒙下一阶段的发展更具信心。
随着鸿蒙市场份额的不断提升,相应的岗位也会迎来一个爆发式的增长。这对于想要换赛道的程序员来说是一个非常好的消息,话说大家最近有想法转型鸿蒙开发吗?
简介
在OpenHarmony应用中,每个 进程 都会有一个主线程,主线程主要承担执行UI绘制操作、管理ArkTS引擎实例的创建和销毁、分发和处理事件、管理Ability生命周期等职责,具体可参见 线程模型概述 。因此,开发应用时应当尽量避免将耗时的操作放在主线程中执行。ArkTS提供了Worker和TaskPool两种多线程并发能力,多线程并发允许在同一时间段内同时执行多段代码,这两个并发的基本能力可参见 TaskPool和Worker的对比 。
在介绍Worker和TaskPool的详细使用方法前,我们先简单介绍并发模型的相关概念,以便于大家的理解。
并发模型概述
并发的意思是多个任务同时执行。并发模型分为两大类:基于内存共享的并发模型和基于消息传递的并发模型。
在基于内存共享的并发模型中,并发线程通过读写内存中的共享对象来进行交互。基于共享内存的并发编程需要满足三条性质:
●原子性:指一个操作是不可中断的,要么全部执行成功要么全部执行失败。
●有序性:指程序执行的顺序必须符合预期,不能出现乱序的情况。
●可见性:指当一个线程修改了共享变量后,其他线程能够立即得知这个修改。
现代程序语言一般通过锁、内存屏障、原子指令来满足这三条性质。基于内存共享的并发模型与底层硬件接近,在能正确撰写并发代码的情况下,可以最大发挥底层硬件性能,实现性能优秀的多线程程序。但是这种并发模型难以掌握,即使资深的程序员也非常容易犯错。典型的基于内存共享并发模型的程序语言有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。OpenHarmony中Worker和TaskPool都是基于Actor并发模型实现的并发能力。
Worker
基本概念和运作原理
OpenHarmony中的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 场景预

最低0.47元/天 解锁文章
1212

被折叠的 条评论
为什么被折叠?



