鸿蒙多线程开发——线程间数据通信对象02

1、前 言

本文的讨论是接续鸿蒙多线程开发——线程间数据通信对象01的讨论。在上一篇文章中,我们讨论了常规的JS对象(普通JSON对象、Object、Map、Array等)、ArrayBuffer。其中讨论了ArrayBuffer的复制传输和转移传输方式。

下面,我们将讨论SharedArrayBuffer。

2、SharedArrayBuffer

SharedArrayBuffer是一种允许多个线程共享相同内存空间的数据通信对象。

这意味着不同的线程可以同时访问和修改相同的数据,而无需复制数据或担心数据同步的问题。SharedArrayBuffer允许我们以更有效的方式进行多线程编程,从而提高性能。

除了SharedArrayBuffer可以直接在多个线程中直接共享外,其他与ArrayBuffer非常类似。

由于SharedArrayBuffer可以在多个线程中直接共享,因此,使用SharedArrayBuffer需要格外小心,以确保线程之间的同步和数据访问是正确的。不正确的访问可能导致内存安全性问题。

为了保证操作的原子性,我们需要使用Atomics类来对数据进行操作。

👉🏻 Atomics

与一般的全局对象不同,Atomics 不是构造函数。我们不能将其与 new 运算符一起使用或将 Atomics 对象作为一个函数来进行调用。

Atomics 的所有属性和方法都是静态的(与 Math 对象一样)。

当SharedArrayBuffer内存被共享时,多个的线程能够读写内存上的同一数据。Atomics原子操作会确保正在读或写的数据的值是符合预期的(即下一个原子操作一定会在上一个原子操作结束后才会开始,其操作不会被中断)。

Atomics提供wait()和notify()机制,采用的是 Linux 上的 futex 模型(“快速用户空间互斥体”),可以让进程一直等待直到某个特定的条件为真,主要用于实现阻塞。

Atomics有如下静态方法,用于实现数据的原子操作:

  • Atomics.add(typedArray, index, value)

    将给定的值与数组上指定位置的元素相加,并返回相加前该元素的值。

  • Atomics.and(typedArray, index, value)

    将指定位置上的数组元素与给定的值相与,并返回与操作前该元素的值。

  • Atomics.compareExchange(typedArray, index, expectedValue, replacementValue)

    如果数组中指定的元素与给定的值相等,则将其更新为新的值,并返回该元素原先的值。

  • Atomics.exchange(typedArray, index, value)

    将数组中指定的元素更新为给定的值,并返回该元素更新前的值。

  • Atomics.load(typedArray, index)

    返回数组中指定元素的值。

  • Atomics.notify(typedArray, index, count)

    通知正在等待数组指定索引的代理。返回收到通知的代理数量。

  • Atomics.or(typedArray, index, value)

    将指定位置上的数组元素与给定的值相或,并返回或操作前该元素的值。

  • Atomics.store(typedArray, index, value)

    将值储存到数组的指定位置,并返回该值。

  • Atomics.sub(typedArray, index, value)

    将指定位置上的数组元素与给定的值相减,并返回相减前该元素的值。

  • Atomics.wait(typedArray, index, value, timeout)

    检测数组中某个指定位置上的值是否仍然是给定值,是则保持挂起直到被唤醒或超时。返回值为 "ok"、"not-equal" 或 "time-out"。调用时,如果当前代理不允许阻塞,则会抛出异常(大多数浏览器都不允许在主线程中调用 wait())。

  • Atomics.waitAsync(typedArray, index, value, timeout)

    在共享内存位置上异步等待(即没有阻塞,与 Atomics.wait 不同)并返回一个 Promise。

  • Atomics.xor(typedArray, index, value,)

    将指定位置上的数组元素与给定的值相异或,并返回异或操作前该元素的值。

Atomics的基本使用示例如下:

const sab = new SharedArrayBuffer(1024);const ta = new Uint8Array(sab);ta[0]; // 0ta[0] = 5; // 5Atomics.add(ta, 0, 12); // 5Atomics.load(ta, 0); // 17Atomics.and(ta, 0, 1); // 17Atomics.load(ta, 0); // 1Atomics.compareExchange(ta, 0, 5, 12); // 1Atomics.load(ta, 0); // 1Atomics.exchange(ta, 0, 12); // 1Atomics.load(ta, 0); // 12Atomics.or(ta, 0, 1); // 12Atomics.load(ta, 0); // 13Atomics.store(ta, 0, 12); // 12Atomics.sub(ta, 0, 2); // 12Atomics.load(ta, 0); // 10Atomics.xor(ta, 0, 1); // 10Atomics.load(ta, 0); // 11

Atomics等待和通知机制

假设有一个SharedArrayBuffer共享内存。如下:​​​​​​​

const sab = new SharedArrayBuffer(1024);const int32 = new Int32Array(sab);

A线程关键代码如下:​​​​​​​

Atomics.wait(int32, 0, 0);consle.log(int32[0]); // 123

由于默认情况下,int32[0]值为0,因此A线程将在代码1行上进行阻塞等待。

此时如果启动了B线程,关键代码如下:​​​​​​​

console.log(int32[0]); // 0;Atomics.store(int32, 0, 123);Atomics.notify(int32, 0, 1);

B线程启动后,第一行代码可以如期打印出初始化的0,紧接着,向SharedArrayBuffer中第0号位,写入了123,然后再调用了notify,发送出一个解锁通知。

A线程中第1行代码的wait在收到通知后,发现0号位已经不等于0了,则执行下一行代码,打印出了B线程写入的123。

示意图如下:

图片

由于篇幅原因Transferable、Sendable我们在后面介绍。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

时序论文22|ICML24港科大:面向多变量不规则的时间序列预测方法

论文标题:Irregular Multivariate Time Series Forecasting: A Transformable Patching Graph Neural Networks Approach 论文链接:https://openreview.net/pdf?idUZlMXUGI6e 前言 这篇文章在“定位研究问题”方面很值得学习。其实前段时间对时序研究…

Linux离线安装Docker命令,简单镜像操作

解压安装包 首先,使用 tar 命令解压 docker-27.3.1.tgz 安装包: tar -zxvf docker-27.3.1.tgz 将二进制文件移动到可执行路径上的目录 接着,将解压出来的 Docker 二进制文件复制到系统的可执行路径(通常是 /usr/bin/&#xff09…

Sigrity SPEED2000 TDR TDT Simulation模式如何进行时域阻抗仿真分析操作指导-差分信号

Sigrity SPEED2000 TDR TDT Simulation模式如何进行时域阻抗仿真分析操作指导-差分信号 Sigrity SPEED2000 TDR TDT Simulation模式如何进行时域阻抗仿真分析操作指导-单端信号详细介绍了单端信号如何进行TDR仿真分析,下面介绍如何对差分信号进行TDR分析,还是以下图为例进行分…

springboot基于微信小程序的食堂预约点餐系统

摘 要 基于微信小程序的食堂预约点餐系统是一种服务于学校和企事业单位食堂的智能化解决方案,旨在提高食堂就餐的效率、缓解排队压力,并优化用户的就餐体验。系统作为一种现代化的解决方案,为食堂管理和用户就餐提供了便捷高效的途径。它不仅…

Java线程池详解

线程池是用来管理和复用线程的一种技术,它避免了频繁的创建和销毁线程的开销,提高了应用程序的性能。在 Java 中,ExecutorService 是一个非常常用的接口,它提供了线程池的基本功能。 1. 线程池的优势 线程复用:线程池…

软件测试—— Selenium 常用函数(二)

前一篇文章:软件测试—— Selenium 常用函数(一)-CSDN博客 目录 前言 一、浏览器 1.常见操作 (1)打开网站 (2)前进、后退、刷新 2.参数设置 (1)设置无头模式 &am…

webgl threejs 云渲染(服务器渲染、后端渲染)解决方案

云渲染和流式传输共享三维模型场景 1、本地无需高端GPU设备即可提供三维项目渲染 云渲染和云流化媒体都可以让3D模型共享变得简单便捷。配备强大GPU的远程服务器早就可以处理密集的处理工作,而专有应用程序,用户也可以从任何个人设备查看全保真模型并与…

springboot基于Spring Boot的古城景区管理系统的设计与实现docx

摘 要 古城景区管理系统是一个集景区导游功能于一体的综合管理平台,旨在提升游客的参观体验和提高管理效率。系统通过提供详尽的热门景点、客房类型、酒店信息、美食类型、特色美食、文创产品及导游服务,使游客能够深入了解古城的历史与文化。该系统集成…

彻底理解如何保证Redis和数据库数据一致性问题

一.背景 系统中缓存最常用的策略是:服务端需要同时维护 DB 和 Cache 并且是以 DB 的结果为准,那么就可能出现 DB 和 Cache 数据不一致的问题。 二.读数据 逻辑如下: 当客户端发起查询数据的请求,首先回去Redis中查看没有没该数据&…

openwebui使用

文章目录 1、feature2、安装使用2.1 安装过程2.2 安装好后 1、feature 可以加载多个大模型 同时回复 模型问答: 使用vLLM框架部署模型,再使用Open WebUI直接进行模型问答 多模型支持: 多模型回复比对(Qwen2-72B-Instruct, llama3-70b-8192, mixtral-8x7…

.net 8使用hangfire实现库存同步任务

C# 使用HangFire 第一章:.net Framework 4.6 WebAPI 使用Hangfire 第二章:net 8使用hangfire实现库存同步任务 文章目录 C# 使用HangFire前言项目源码一、项目架构二、项目服务介绍HangFire服务结构解析HangfireCollectionExtensions 类ModelHangfireSettingsHttpAuthInfoUs…

【已解决】“EndNote could not connect to the online sync service”问题的解决

本人不止一次在使用EndNote软件时遇到过“EndNote could not connect to the online sync service”这个问题。 过去遇到这个问题都是用这个方法来解决: 这个方法虽然能解决,但工程量太大,每次做完得歇半天身体才能缓过来。 后来再遇到该问…

私有化部署视频平台EasyCVR宇视设备视频平台如何构建视频联网平台及升级视频转码业务?

在当今数字化、网络化的时代背景下,视频监控技术已广泛应用于各行各业,成为保障安全、提升效率的重要工具。然而,面对复杂多变的监控需求和跨区域、网络化的管理挑战,传统的视频监控解决方案往往显得力不从心。 EasyCVR视频融合云…

Ubuntu从入门到精通(二)远程和镜像源配置齐全

Ubuntu从入门到精通(二) 1 常见操作配置 1.1 英文语言配置 1.1.1 打开设置 1.1.2 设置语言为英文 1.1.3 重启生效 1.1.4 再次进入,选择更新名字 1.1.5 再次进入,发现已经变成了英文 1.2 输入法配置 1.3 rustdesk安装 1.3.1 Windows系统配置 登陆:https://github.com…

【Node.js】全面解析 Node.js 安全最佳实践:保护您的应用

Node.js 是一种强大的 JavaScript 运行时,广泛用于构建现代 Web 应用和 API。然而,由于其开放性和异步特性,Node.js 应用容易受到多种安全威胁的攻击,比如 SQL 注入、跨站脚本 (XSS) 和拒绝服务攻击 (DoS)。在本文中,我…

Spring Cloud Alibaba、Spring Cloud 与 Spring Boot各版本的对应关系

参考spring-cloud-alibaba github wiki说明:版本说明 下面截取说明: 2022.x 分支 2021.x 分支 2.2.x 分支 组件版本关系

ChatGPT Search VS Kimi探索版:AI搜索哪家强?!

大家好,我是木易,一个持续关注AI领域的互联网技术产品经理,国内Top2本科,美国Top10 CS研究生,MBA。我坚信AI是普通人变强的“外挂”,专注于分享AI全维度知识,包括但不限于AI科普,AI工…

Linux常用命令,持续更新钟

在Linux系统中,你可以使用多种命令来拷贝和移动文件及目录。以下是常用的几个命令及其用法: 一、拷贝文件或目录 cp 命令 cp 命令用于拷贝文件或目录。 拷贝文件: cp source_file destination_file 例如: cp file1.txt /hom…

基于SpringBoot的校园二手商品在线交易系统+含项目运行说明文档

一、项目技术栈 二、项目功能概述 管理员可以完成的功能包括管理员登录、管理员首页展示、系统设置、物品管理、学生管理、评论管理、举报管理、新闻公告、网站设置等,前台的客户可以进行查看所有商品分类、搜索商品、登录或注册、发布商品、求购商品等。 三、部分…

MATLAB实现GARCH(广义自回归条件异方差)模型计算VaR(Value at Risk)

MATLAB实现GARCH(广义自回归条件异方差)模型计算VaR(Value at Risk) 1.计算模型介绍 使用GARCH(广义自回归条件异方差)模型计算VaR(风险价值)时,方差法是一个常用的方法。GARCH模型能够捕捉到金融时间序列数据中的波…