写点什么

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

作者:威哥爱编程
  • 2025-01-13
    北京
  • 本文字数:2259 字

    阅读完需:约 7 分钟

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

案例代码

1. 主线程代码

@Componentexport 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. 子线程代码

@Concurrentasync 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. 主线程初始化共享内存

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

  3. 子线程写入文件

  4. 子线程根据主线程传入的 SharedArrayBuffer 初始化锁和偏移量。

  5. 使用锁确保线程安全,避免多个线程同时写入文件时出现数据竞争。

  6. 通过 Atomics.storeAtomics.load 操作共享内存,实现线程间的同步。

  7. 线程间参数传递

  8. 使用 taskpool.Task 创建子线程任务,并通过 taskpool.execute 执行。

  9. 子线程任务通过 createWriteTask 函数实现,该函数接收主线程传递的参数,包括文件路径、写入内容、锁标志位和偏移位。

  10. 线程安全写入

  11. 在写入文件前,如果启用锁,则获取锁;写入完成后释放锁,确保线程安全。

  12. 通过修改共享内存中的偏移量,指定下次写入的位置,实现线程间的协作。


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

发布于: 20 分钟前阅读数: 9
用户头像

华为 HDE、CSDN 博客专家、Java畅销书作者 2018-05-30 加入

全栈领域优质创作者(Java/HarmonyOS/AI),公众号:威哥爱编程

评论

发布
暂无评论
鸿蒙 NEXT 开发中,普通对象跨线程如何传递_HarmonyOS_威哥爱编程_InfoQ写作社区