鸿蒙 Next 实现线程之间的通信

devtools/2025/3/19 3:07:07/

鸿蒙 Next 实现线程之间的通信

在鸿蒙 Next 开发中,线程间通信是一个常见需求,尤其是在多线程任务处理中。鸿蒙 Next 提供了多种机制来实现线程间通信,包括事件驱动的 Emitter、共享内存 SharedArrayBuffer 以及基于消息传递的 WorkerTaskPool。本文将详细介绍这些机制的使用方法和实现示例。


一、使用 Emitter 实现线程间通信

Emitter 是鸿蒙 Next 提供的一种事件驱动机制,用于实现线程间的通信。它支持事件的订阅、发送和取消订阅。

(一)订阅事件

在主线程或子线程中订阅事件,定义事件回调函数来处理事件。

import { emitter } from '@kit.BasicServicesKit';
import { promptAction } from '@kit.ArkUI';const event = {eventId: 1,
};const callback = (eventData: emitter.EventData) => {promptAction.showToast({message: JSON.stringify(eventData),});
};emitter.on(event, callback);

(二)发送事件

在主线程或子线程中发送事件,将事件数据传递给订阅者。

import { emitter } from '@kit.BasicServicesKit';const event = {eventId: 1,priority: emitter.EventPriority.LOW,
};const eventData = {data: {content: 'Hello from thread',id: 1,isEmpty: false,},
};emitter.emit(event, eventData);

二、使用 SharedArrayBuffer 实现跨线程共享内存

SharedArrayBuffer 是一种低级的跨线程共享内存机制,适用于需要高性能通信的场景。

(一)主线程初始化共享内存

在主线程中初始化 SharedArrayBuffer,并将其传递给子线程。

@Component
export struct LockUsage {sabInLock: SharedArrayBuffer = new SharedArrayBuffer(4);sabForLine: SharedArrayBuffer = new SharedArrayBuffer(4);build() {// 初始化子线程锁标志位和偏移位Atomics.store(new Int32Array(this.sabInLock), 0, 0);Atomics.store(new Int32Array(this.sabForLine), 0, 0);}
}

(二)子线程使用共享内存

在子线程中,通过 SharedArrayBuffer 进行线程间通信。

@Concurrent
async function createWriteTask(sabInLock: SharedArrayBuffer, sabForLine: SharedArrayBuffer) {const lock = new NonReentrantLock(sabInLock);const whichLineToWrite = new Int32Array(sabForLine);lock.lock();try {// 执行任务console.log('Writing to line:', whichLineToWrite[0]);whichLineToWrite[0] += 1; // 更新偏移量} finally {lock.unlock();}
}

三、使用 Worker 和 TaskPool 实现线程间通信

WorkerTaskPool 是基于消息传递的线程间通信机制,适用于处理复杂的异步任务。

(一)使用 Worker

Worker 是一个独立的线程,可以执行耗时任务,通过消息传递与主线程通信。

主线程代码
@Entry
@Component
struct MainWorkerComponent {build() {const worker = new Worker('worker.js');worker.onMessage = (message) => {console.info('Main thread received:', message.data);};worker.postMessage({ task: 'processData', data: [1, 2, 3] });}
}
Worker 代码(worker.js)
onmessage = function(event) {const { task, data } = event.data;if (task === 'processData') {const result = data.map(item => item * 2);postMessage({ result });}
};

(二)使用 TaskPool

TaskPool 是一个线程池,用于管理多个任务的执行。

class ThreadPool {constructor(public maxThreads: number) {this.pool = [];}runTask(task) {if (this.pool.length < this.maxThreads) {const worker = new Worker('worker.js');this.pool.push(worker);worker.onMessage = (message) => {console.info('Task completed:', message.data);this.releaseWorker(worker);};worker.postMessage({ task });} else {console.info('All threads are busy, retrying...');setTimeout(() => this.runTask(task), 1000);}}releaseWorker(worker) {this.pool = this.pool.filter(w => w !== worker);worker.terminate();}
}

四、总结

鸿蒙 Next 提供了多种线程间通信机制,包括事件驱动的 Emitter、共享内存的 SharedArrayBuffer 和基于消息传递的 WorkerTaskPool。开发者可以根据具体需求选择合适的机制来实现线程间通信,确保线程安全和数据一致性。

希望本文能帮助你更好地理解和实现鸿蒙 Next 中的线程间通信。如果有任何问题或需要进一步讨论,欢迎随时交流!


http://www.ppmy.cn/devtools/168221.html

相关文章

通过 CSS 的 命名页面(Named Pages) 技术实现作用域隔离,实现 @page 样式仅影响当前组件

以下是实现 page 样式仅影响当前组件的完整解决方案&#xff0c;通过 CSS 的 命名页面&#xff08;Named Pages&#xff09; 技术实现作用域隔离&#xff1a; vue <template><div><button v-print"printOptions">打印当前报表</button><…

MySQL复习笔记

文章目录 1.MySQL1.1什么是数据库1.2 数据库分类1.3 MySQL简介1.4连接数据库 2. 操作数据库2.1 操作数据库2.2 数据库的列类型2.3 数据库的字段属性&#xff08;重点&#xff09;2.4 创建数据库表&#xff08;重点&#xff09;2.5 数据表的类型2.6 修改数据表 3. MySQL 数据管理…

WebLogic XMLDecoder反序列化漏洞(CVE-2017-10271)深度解析与实战复现

0x00 漏洞概述 CVE-2017-10271 是Oracle WebLogic Server WLS Security组件中的远程代码执行漏洞。攻击者通过构造恶意XML请求&#xff0c;利用XMLDecoder反序列化机制绕过安全验证&#xff0c;最终实现服务器权限接管。 影响版本 WebLogic 10.3.6.0WebLogic 12.1.3.0WebLog…

第十五届蓝桥杯C/C++B组拔河问题详解

解题思路 这道题目的难点在于枚举所有区间&#xff0c;并且区间不能重合&#xff0c;那么这样感觉就很难了。但是用下面这种方法就会好很多。 我们只需要将左边的所有区间的各种和放在一个set中&#xff0c;然后我们在枚举右边的所有区间的和去和它进行比较&#xff0c;然后…

基于图神经网络(GNN)的节点分类实战:从GCN到GraphSAGE

图神经网络(GNN)是一种专门用于处理图结构数据的深度学习模型,广泛应用于社交网络分析、推荐系统和生物信息学等领域。图卷积网络(GCN)是GNN的经典方法,而GraphSAGE则通过引入采样机制进一步提升了其性能。本文将通过一个完整的实战案例,展示如何使用GCN和GraphSAGE对图…

基于CNN的多种类蝴蝶图像分类

基于CNN的多种类蝴蝶图像分类&#x1f98b; 基于卷积神经网络对64992786张图像&#xff0c;75种不同类别的蝴蝶进行可视化分析、模型训练及分类展示 导入库 import pandas as pd import os import matplotlib.pyplot as plt import seaborn as sns import numpy as np from …

Android第三次面试(Java基础)

面试题一&#xff1a;在 Android 里&#xff0c;Array 和 ArrayList 区别&#xff1f; 定义与大小&#xff1a;数组声明时要指定大小&#xff0c;之后固定&#xff1b;ArrayList 动态&#xff0c;无需提前定大小。性能&#xff1a;二者访问元素快&#xff0c;时间复杂度 O(1)&…

vue/react/vite前端项目打包的时候加上时间最简单版本,防止后端扯皮

如果你是vite项目&#xff0c;直接写一个vite的插件&#xff0c;通过这个插件可以动态注入环境变量&#xff0c;然后当打包的时候&#xff0c;自动注入这个时间到环境变量中&#xff0c;然后在项目中App.vue中或者Main.tsx中打印出来&#xff0c;这就知道是什么时候编译的项目了…