首页 > 其他分享 >鸿蒙 NEXT 开发中,普通对象跨线程如何传递

鸿蒙 NEXT 开发中,普通对象跨线程如何传递

时间:2025-01-13 10:22:34浏览次数:1  
标签:useLock string 鸿蒙 SharedArrayBuffer NEXT let 线程 共享内存

大家好,我是 V 哥,在鸿蒙HarmonyOS NEXT开发中,跨线程对象传递可以通过拷贝形式实现,确保两个线程的对象内容一致,但各自指向线程的隔离内存区间。以下是使用SharedArrayBuffer实现跨线程共享内存的完整案例代码,包括详细解释,整理的学习笔记,分享给大家。关注威哥不迷路,学习鸿蒙就很酷。

案例代码

1. 主线程代码

@Component
export struct LockUsage {
  taskNum: number = 10; // 任务数,实际并行线程数依设备而定
  baseDir: string = getContext().filesDir + '/TextDir'; // 文件写入的应用沙箱路径
  sabInLock: SharedArrayBuffer = new SharedArrayBuffer(4); // 在主线程,初始化子线程锁标志位,所使用的共享内存
  sabForLine: SharedArrayBuffer = new SharedArrayBuffer(4); // 在主线程,初始化子线程偏移位,所使用的共享内存
  @State result: string = "";
  build() {
    Row() {
      Column() {
        Button($r('app.string.not_use_lock'))
          .width("80%").fontSize(30)
          .fontWeight(FontWeight.Bold)
          .margin({ top: 30 })
          .onClick(async () => {
            this.startWrite(false);
          })
        Button($r('app.string.use_lock'))
          .width("80%")
          .fontSize(30)
          .fontWeight(FontWeight.Bold)
          .margin({ top: 30 })
          .onClick(async () => {
            this.startWrite(true);
          })
        Text(this.result)
          .width("80%")
          .fontSize(30)
          .fontWeight(FontWeight.Bold)
          .fontColor(Color.Blue)
          .margin({ top: 30 })
      }
      .width('100%')
    }
    .height('100%')
  }
  startWrite(useLock: boolean): void {
    this.result = getContext().resourceManager.getStringSync($r('app.string.write_file_start'));
    let whichLineToWrite: Int32Array = new Int32Array(this.sabForLine);
    Atomics.store(whichLineToWrite, 0, 0);
    let taskPoolGroup: taskpool.TaskGroup = new taskpool.TaskGroup();
    for (let i: number = 0; i < this.taskNum; i++) {
      taskPoolGroup.addTask(new taskpool.Task(createWriteTask, this.baseDir, i, this.sabInLock, this.sabForLine, useLock));
    }
    taskpool.execute(taskPoolGroup).then(() => {
      this.result = getContext().resourceManager.getStringSync($r('app.string.write_file_success'));
    }).catch(() => {
      this.result = getContext().resourceManager.getStringSync($r('app.string.write_file_failed'));
    })
  }
}

2. 子线程代码

@Concurrent
async function createWriteTask(baseDir: string, writeText: number, sabInLock: SharedArrayBuffer, sabForLine: SharedArrayBuffer, useLock: boolean): Promise<void> {
  class Option { 
    offset: number = 0;
    length: number = 0;
    encoding: string = 'utf-8';
    constructor(offset: number, length: number) {
      this.offset = offset;
      this.length = length;
    }
  }
  let filePath: string | undefined = undefined;
  filePath = baseDir + useLock ? "/useLock.txt" : "/unusedLock.txt";
  if (!fs.accessSync(baseDir)) {
    fs.mkdirSync(baseDir);
  }
  let nrl: NonReentrantLock | undefined = undefined;
  if (useLock) {
    nrl = new NonReentrantLock(sabInLock);
  }
  let whichLineToWrite: Int32Array = new Int32Array(sabForLine);
  let str: string = writeText + '\n';
  for (let i: number = 0; i < 100; i++) {
    if (useLock && nrl !== undefined) {
      nrl.lock();
    }
    let file: fs.File = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
    try {
      fs.writeSync(file.fd, str, new Option(whichLineToWrite[0], str.length));
    } catch (err) {
      logger.error(`errorCode : ${err.code},errMessage : ${err.message}`);
    }
    fs.closeSync(file);
    whichLineToWrite[0] += str.length;
    if (useLock && nrl !== undefined) {
      nrl.unlock();
    }
  }
}

详细解释

  1. 主线程初始化共享内存

    • sabInLocksabForLine 是两个 SharedArrayBuffer 对象,分别用于子线程锁标志位和偏移位。它们在主线程中被初始化,并将被传递给子线程,实现跨线程共享内存。
  2. 子线程写入文件

    • 子线程根据主线程传入的 SharedArrayBuffer 初始化锁和偏移量。
    • 使用锁确保线程安全,避免多个线程同时写入文件时出现数据竞争。
    • 通过 Atomics.storeAtomics.load 操作共享内存,实现线程间的同步。
  3. 线程间参数传递

    • 使用 taskpool.Task 创建子线程任务,并通过 taskpool.execute 执行。
    • 子线程任务通过 createWriteTask 函数实现,该函数接收主线程传递的参数,包括文件路径、写入内容、锁标志位和偏移位。
  4. 线程安全写入

    • 在写入文件前,如果启用锁,则获取锁;写入完成后释放锁,确保线程安全。
    • 通过修改共享内存中的偏移量,指定下次写入的位置,实现线程间的协作。

这个案例展示了如何在鸿蒙HarmonyOS NEXT开发中实现跨线程对象传递和共享内存,确保线程安全和数据一致性。通过使用 SharedArrayBuffer 和线程间参数传递,可以实现高效的并发编程。关注威哥爱编程,一起向鸿蒙出发。

标签:useLock,string,鸿蒙,SharedArrayBuffer,NEXT,let,线程,共享内存
From: https://www.cnblogs.com/wgjava/p/18668050

相关文章

  • Qt多线程开发全解析
     目录一、引言二、Qt多线程基础概念2.1线程与进程2.2Qt中的线程类三、Qt多线程的使用场景3.1耗时操作处理3.2实时数据处理3.3多任务并发执行四、Qt多线程的实现方式4.1继承QThread类4.2使用QThreadPool线程池4.3利用QtConcurrent框架五、线程间的同步......
  • 【HarmonyOS Next NAPI 深度探索2】N-API 的工作机制与架构
    【HarmonyOSNextNAPI深度探索2】N-API的工作机制与架构如果你听说过N-API,但还不太了解它的作用和背后的工作机制,那这篇文章会帮你捋清楚它的结构和原理。N-API是Node.js提供的一个强大工具,专门用于开发高性能、可维护的原生模块。接下来,我们一起看看N-API是如何......
  • 分析基于ASP.NET Core Kernel的gRPC服务在不同.NET版本的不同部署方式的不同线程池下
    分析基于ASP.NETCoreKernel的gRPC服务在不同.NET版本的不同部署方式的不同线程池下的性能表现使用默认的gRPC项目模板创建,垃圾回收器类型为ServerGC(Servergarbagecollection)。使用ghz工具在不同的请求总数、连接数、并发数的参数下,进行压力测试,接口为/greet.G......
  • Python 魔法学院 - 第18篇:Python 多线程 ⭐⭐⭐
    目录引言1.多线程编程基础1.1什么是多线程?1.2为什么需要多线程?1.3Python中的多线程模块2.创建和启动线程2.1使用`threading.Thread`创建线程2.2使用`target`参数创建线程3.线程同步3.1为什么需要线程同步?3.2使用`Lock`实现线程同步3.3使用`RLock`......
  • rust学习十六.3、并发-线程之间共享数据
    线程之间共享数据,即go中部分人所憎恶的方式!然而,这个方式并非没有其优点,否则操作系统也不提供这种实现方式。 闲言少序,上正文!一、概述 *1.当我们大谈基于信道通信时,应该指的是应用级别。如果是操作系统,应该还是会有多种措施的,否则rust的源头在哪里来着。 *2.rust共享内......
  • workerpool,JavaScript强大的线程池库!
    ......
  • MySQL sleep 线程过多怎么解决
    1知道sleep线程过多原因首先要知道到底是什么原因导致的sleep线程过多的:程序逻辑问题,导致连接一直不释放;mysql参数的问题,是不是参数配置的不合理,一直不释放连接;mysql语句的问题,数据库查询不够优化,过度耗时。大并发情况问题,导致sleep情况过多;2临时解决s......
  • 【HarmonyOS Next NAPI 深度探索1】Node.js 和 CC++ 原生扩展简介
    【HarmonyOSNextNAPI深度探索1】Node.js和CC++原生扩展简介如果你用过Node.js,应该知道它强大的地方在于能处理各种场景,速度还很快。但你有没有想过,Node.js的速度秘密是什么?今天我们来聊聊其中一个幕后英雄——原生扩展,特别是如何通过C/C++把JavaScript的能力进......
  • 1.4. 线程状态转化及源码解读
    2.init()packageThreadPackage;publicclassThreadTest{publicstaticvoidmain(String[]args){//创建一个线程,显式调用Thread的构造函数Threadthread=newThread(()->{System.out.println("线程运行");},"M......
  • #【鸿蒙面试题】分享几个不怎么注意到的面试题
    Navigation中哪个生命周期可以获取到页面栈,怎么获取的?Navigation的onReady生命周期中可以获取到页面栈,通过回调函数获取的。.onReady((context:NavDestinationContext)=>{context.pathStack})鸿蒙的后台任务类型有哪些短时任务:实时性要求较高的任务,比如状态保存长时任......