鸿蒙多线程开发——并发模型对比(Actor与内存共享)

1、概 述

并发是指在同一时间段内,能够处理多个任务的能力。为了提升应用的响应速度与帧率,以及防止耗时任务对主线程的干扰,HarmonyOS系统提供了异步并发和多线程并发两种处理策略。

  • 异步并发:指异步代码在执行到一定程度后会被暂停,以便在未来某个时间点继续执行,这种情况下,同一时间只有一段代码在执行。

  • 多线程并发:它允许在同一时间段内同时执行多段代码。在主线程继续响应用户操作和更新UI的同时,后台也能执行耗时操作,从而避免应用出现卡顿。

并发能力在多种场景中都有应用,其中包括单次I/O任务、CPU密集型任务、I/O密集型任务和同步任务等。我们可以根据不同的场景,选择相应的并发策略进行优化和开发。

ArkTS支持异步并发和多线程并发。

    • Promise和async/await提供异步并发能力,适用于单次I/O任务的开发场景。(之前我们已经讨论过,参看文章👉🏻 异步场景: promise、async函数与await命令介绍)

    • TaskPool和Worker提供多线程并发能力,适用于CPU密集型任务、I/O密集型任务和同步任务等并发场景。

目前ArkTs提供的多线程并发能力都基于Actor并发模型,在介绍TaskPool和Worker前,我们先了解下多线程并发中的两个并发模型:Actor并发模型、内存共享并发模型。

为了解释两个并发模型,后文以经典的生产者消费者问题为例,对比呈现这两种模型在解决具体问题时的差异。

2、Actor并发模型

Actor并发模型中,每一个线程都是一个独立Actor,每个Actor有自己独立的内存,Actor之间通过消息传递机制触发对方Actor的行为,不同Actor之间不能直接访问对方的内存空间。

⭐️ Actor并发模型特点:Actor模型不同角色之间并不共享内存,生产者线程和UI线程都有自己独占的内存。

在生产者消费者问题中,过程为:生产者生产出结果后通过序列化通信将结果发送给UI线程,UI线程消费结果后再发送新的生产任务给生产者线程。示意图如下:

图片

以下示例简单展示了如何使用基于Actor模型的TaskPool并发能力来解决生产者消费者问题【重点关注4~8行,11~14行,35~39行】。

import { taskpool } from '@kit.ArkTS';// 跨线程并发任务@Concurrentasync function produce(): Promise<number>{  // 添加生产相关逻辑  console.log("producing...");  return Math.random();}class Consumer {  public consume(value : Object) {    // 添加消费相关逻辑    console.log("consuming value: " + value);  }}@Entry@Componentstruct Index {  @State message: string = 'Hello World'  build() {    Row() {      Column() {        Text(this.message)          .fontSize(50)          .fontWeight(FontWeight.Bold)        Button() {          Text("start")        }.onClick(() => {          let produceTask: taskpool.Task = new taskpool.Task(produce);          let consumer: Consumer = new Consumer();          for (let index: number = 0; index < 10; index++) {            // 执行生产异步并发任务            taskpool.execute(produceTask).then((res : Object) => {              consumer.consume(res);            }).catch((e : Error) => {              console.error(e.message);            })          }        })        .width('20%')        .height('20%')      }      .width('100%')    }    .height('100%')  }}

3、内存共享并发模型

内存共享并发模型中,多个线程同时执行复数任务,这些线程依赖同一内存并且都有权限访问,线程访问内存前需要抢占并锁定内存的使用权,没有抢占到内存的线程需要等待其他线程释放使用权再执行。

⭐️ 内存共享并发模型特点:线程间共享内存,内存的操作有排他性。

为了避免不同生产者或消费者同时访问一块共享内存的容器时产生的脏读,脏写现象,同一时间只能有一个生产者或消费者访问该容器,也就是不同生产者和消费者争夺使用容器的锁。当一个线程获取锁之后其他线程需要等待该线程释放锁之后才能重新尝试获取锁以访问该容器。示意图如下:

图片

以下示例伪代码和示意图展示了如何使用内存共享模型解决生产者消费者问题。

// 此段示例为伪代码仅作为逻辑示意,便于开发者理解使用内存共享模型和Actor模型的区别BufferQueue {    Queue queue    Mutex mutex    add(value) {        // 尝试获取锁        if (mutex.lock()) {            queue.push(value)            mutex.unlock()        }    }    take() {        // 尝试获取锁        if (mutex.lock()) {            if (queue.empty()) {                return null            }            let res = queue.pop(value)            mutex.unlock()            return res        }    }}// 构造一段全局共享的内存let g_bufferQueue = new BufferQueue()Producer {    run() {        let value = random()        // 跨线程访问bufferQueue对象        g_bufferQueue.add(value)    }}Consumer {    run() {        // 跨线程访问bufferQueue对象        let res = g_bufferQueue.take()        if (res != null) {            // 添加消费逻辑        }    }}Main() {    let consumer = new Consumer()    let producer = new Producer()    // 多线程执行生产任务    for 0 in 10 :        let thread = new Thread()        thread.run(producer.run())        consumer.run()}​​​​​​​
Actor并发模型对比内存共享并发模型的优势在于不同线程间内存隔离,不会产生不同线程竞争同一内存资源的问题。开发者不需要考虑对内存上锁导致的一系列功能、性能问题,提升了开发效率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/911567.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++builder中的人工智能(12):了解ELU(Exponential Linear Unit)——人工神经网络中的激活函数

在这篇文章中&#xff0c;我们将解释什么是指数线性单元&#xff08;ELU&#xff09;&#xff0c;以及如何利用ELU激活函数。通过学习这些知识&#xff0c;你将能够使用C软件创建C应用程序。 我们需要了解哪些关于激活函数的知识&#xff1f; 激活函数&#xff08;phi()&#…

Spark中的宽窄依赖-宽窄巷子

1、什么是依赖关系&#xff1f; 2、什么是宽窄依赖&#xff1f; 窄依赖&#xff1a;Narrow Dependencies 定义&#xff1a;父RDD的一个分区的数据只给了子RDD的一个分区 【不用经过Shuffle】 特点&#xff1a;一对一或者多对一&#xff0c;不经过Shuffle&#xff0c;性能相对…

Scrapy入门

Scrapy 是用 Python 实现的一个为了爬取网站数据、提取结构性数据而编写的应用框架。 安装scrapy pip install scrapy2.5.0 1.新建 Scrapy项目 scrapy startproject mySpider # 项目名为mySpider 2.进入到spiders目录 cd mySpider/mySpider/spiders 3.创建爬虫 scrapy gensp…

C++ 继承:代码传承的魔法棒,开启奇幻编程之旅

文章目录 一.继承的概念及定义1.1继承的概念1.2继承类1.2.1继承方法 1.3继承模板 二.基类和派生类的转换三.继承中的作用域四.派生类的默认成员函数4.1默认成员函数的行为4.2实现一个无法被继承的类 五.继承与友元六.继承与静态成员七.多继承和菱形继承7.1多继承和菱形继承7.2虚…

Liunx:文件fd、重定向、管道

文件fd&#xff1a; 操作系统运行中一定存在着许多被打开的文件&#xff0c;这些文件需要被管理。一个进程会打开若干个文件。一个文件如果在操作系统中被打开&#xff0c;那么必须给该文件创建一个文件对象&#xff0c;包含被打开文件的各种属性。那么进程与文件的关系就变成…

【AIGC】ChatGPT提示词Prompt高效编写技巧:逆向拆解OpenAI官方提示词

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;OpenAI官方提示词的介绍OpenAI官方提示词的结构与组成如何通过分析提示词找到其核心组件 &#x1f4af;OpenAI官方提示词分析案例一&#xff1a;制定教学计划案例二&…

干部谈话考察系统:革新传统,精准高效

在干部选拔任用和考核评价的过程中&#xff0c;谈话考察一直是关键环节之一。然而&#xff0c;传统的谈话考察方式却面临着诸多痛点&#xff0c;严重影响了干部考察工作的质量和效率。干部谈话考察系统的出现&#xff0c;为解决这些问题提供了有力的武器。 一、传统谈话考察的…

细说STM32单片机USART中断收发RTC实时时间并改善其鲁棒性的另一种方法

目录 一、工程目的 1、目标 2、通讯协议及应对错误指令的处理目标 二、工程设置 三、程序改进 四、下载与调试 1、合规的指令 2、不以#开头&#xff0c;但以&#xff1b;结束&#xff0c;长度不限 3、以#开头&#xff0c;不以;结束&#xff0c;也不包含;&#xff0c;长…

轨迹规划中优化预测:学习多个初始解的优化器

Abstract 在许多应用中&#xff0c;如机器人控制、自动驾驶和投资组合管理&#xff0c;需要在严格的运行时间限制下连续地解决相似的优化问题。在这种情况下&#xff0c;局部优化方法的性能对初始解的质量非常敏感&#xff1a;不良的初始化可能会导致收敛缓慢或得到次优解。为…

Xserver v1.4.2发布,支持自动重载 nginx 配置

Xserver——优雅、强大的 php 集成开发环境 本次更新为大家带来了更好的用户体验。 &#x1f389; 下载依赖组件时&#xff0c;显示进度条&#xff0c;展示下载进度。 &#x1f389; 保存站点信息和手动修改 vhost 配置文件之后&#xff0c;自动重载 nginx 配置 &#x1f41e…

idea 基础简单应用(java)

Java IDE&#xff08;集成开发环境&#xff09;的使用方法因不同的IDE而异&#xff0c;但通常都包含一些基本的操作和功能。以下以IntelliJ IDEA这一流行的Java IDE为例&#xff0c;介绍Java IDE的基本使用方法与指南&#xff1a; 一、下载与安装 请点击观看 idea免费安装步…

Notepad++ 更改字体大小和颜色

前言 在长时间编程或文本编辑过程中&#xff0c;合适的字体大小和颜色可以显著提高工作效率和减少眼睛疲劳。Notepad 提供了丰富的自定义选项&#xff0c;让你可以根据个人喜好调整编辑器的外观。 步骤详解 1. 更改字体大小 打开 Notepad 启动 Notepad 编辑器。 进入设置菜…

五个高质量伤感视频素材资源站,帮你快速找到完美创作素材

在制作短视频、MV或者广告时&#xff0c;伤感主题的视频素材往往能触动观众的情感&#xff0c;让作品更具共鸣。无论是表达分手、离别&#xff0c;还是展现孤独与失落&#xff0c;合适的伤感素材对情感类创作至关重要。为帮助创作者找到优质的视频素材&#xff0c;以下推荐5个高…

理解Web登录机制:会话管理与跟踪技术解析(一)

在这篇博客中&#xff0c;我们将深入探讨登录校验、会话技术和会话跟踪技术的基本概念、实现原理及其在Web应用中的应用。我们将介绍常见的会话跟踪技术&#xff0c;如Cookies、Session&#xff0c;并讨论它们的优缺点。同时&#xff0c;我们也会涉及如何使用现有的技术栈来实现…

ffmpeg:视频字幕嵌入(GPU加速)

实现方案 参考指令 ffmpeg -i input_video.mp4 -vf "subtitlessubtitles.srt" output_video.mp4 解决因文件名称复杂导致的指令执行失败问题&#xff08;引号给文件框起来&#xff09; ffmpeg -i "A.mp4" -vf "subtitlesB.srt" "c.mp4&qu…

qt QListWidget详解

1、概述 QListWidget 是 Qt 框架中的一个类&#xff0c;它提供了一个基于模型的视图&#xff0c;用于显示项目的列表。QListWidget 继承自 QAbstractItemView 并为项目列表提供了一个直观的接口。与 QTreeView 和 QTableView 不同&#xff0c;QListWidget 是专门为单行或多行项…

UE5 材质篇 0 创建一个材质

首先在starter里的shape里拖入一个几何到场景里 我选了个sphere 然后开始制作一个材质&#xff0c;直接右键点击 进入材质的蓝图界面 先来个纹理采样 左侧detail里选个图给他 type这里可以指定他是其他图片&#xff0c;例如normal map 采样一个之前给UV加个动态offset

AOSP沙盒android 11

这里介绍一下aosp装系统 什么是aosp AOSP&#xff08;Android Open Source Project&#xff09;是Android操作系统的开源版本。 它由Google主导&#xff0c;提供了Android的源代码和相关工具&#xff0c;供开发者使用和修改。 AOSP包含了Android的核心组件和API&#xff0c;使…

Linux挖矿病毒(kswapd0进程使cpu爆满)

一、摘要 事情起因:有台测试服务器很久没用了&#xff0c;突然监控到CPU飙到了95以上&#xff0c;并且阿里云服务器厂商还发送了通知消息&#xff0c;【阿里云】尊敬的xxh: 经检测您的阿里云服务&#xff08;ECS实例&#xff09;i-xxx存在挖矿活动。因此很明确服务器中挖矿病毒…

flink 内存配置(二):设置TaskManager内存

flink 内存配置&#xff08;一&#xff09;&#xff1a;设置Flink进程内存 flink 内存配置&#xff08;二&#xff09;&#xff1a;设置TaskManager内存 flink 内存配置&#xff08;三&#xff09;&#xff1a;设置JobManager内存 flink 内存配置&#xff08;四&#xff09;…