> 技术文档 > 鸿蒙中 线程间通信

鸿蒙中 线程间通信


本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新

一、线程的实现方式

鸿蒙提供了多种线程管理方案,适用于不同场景:

1. 基于ArkTS/JS的异步任务(TaskPool)
  • 用途:执行CPU密集型任务(如数据处理、图像解码)。
  • 特点
    • 轻量级线程池(TaskPool)管理,自动调度。
    • 任务之间隔离,崩溃不影响主线程。
  • 示例
 import taskpool from \'@ohos.taskpool\'; @Concurrent function computeTask(data: number): number { return data * 2; // 在子线程中执行 } async function runTask() { const task = new taskpool.Task(computeTask, 100); const result = await taskpool.execute(task); // 提交到线程池 console.log(`Result: ${result}`); }

关键点

  • @Concurrent 装饰器是必须的,表示该函数可并发执行。
  • 任务参数需可序列化(不支持回调函数、类实例等)。
2. Worker线程
  • 用途:长时间运行的后台任务(如网络请求、文件IO)。
  • 特点
    • 独立线程,与主线程通过消息通信
    • 需单独创建worker.ts文件。
  • 示例

步骤1:创建Worker文件entry/src/main/ets/workers目录下创建FileWorker.ts

// workers/FileWorker.tsimport worker from \'@ohos.worker\';// 1. 获取Worker通信端口const workerPort = worker.workerPort;// 2. 监听主线程消息workerPort.onmessage = (msg: MessageEvents) => { console.log(`Worker收到消息: ${JSON.stringify(msg.data)}`); // 模拟耗时操作(如文件处理) setTimeout(() => { workerPort.postMessage({ status: \'done\', result: msg.data * 2 }); // 返回结果 }, 1000);};// 3. 错误处理workerPort.onerror = (err: ErrorEvent) => { console.error(`Worker发生错误: ${err.message}`);};

步骤2:主线程调用

// 主线程代码const worker = new worker.ThreadWorker(\'entry/ets/workers/FileWorker.ts\');// 1. 发送消息到Workerworker.postMessage(42); // 传递数据// 2. 接收Worker返回结果worker.onmessage = (msg: MessageEvents) => { console.log(`主线程收到结果: ${JSON.stringify(msg.data)}`); // 输出: 主线程收到结果: {\"status\":\"done\",\"result\":84}};// 3. 销毁Worker(不再需要时)worker.terminate();

关键点

  • Worker文件路径需相对于entry/src/main/ets
  • 通过postMessageonmessage实现双向通信。

二、线程间通信(IPC)方式

1. 消息传递(Worker/TaskPool)
  • 机制:基于序列化数据的跨线程消息。
  • 适用场景:ArkTS/JS层线程通信。
方法 说明 示例 postMessage 发送消息 worker.postMessage({key: value}) onmessage 接收消息 worker.onmessage = (msg) => {} terminate 终止Worker worker.terminate()
2. 共享内存(SharedArrayBuffer)
  • 机制:多线程直接读写同一块内存。
  • 注意:需手动同步避免竞态条件。
// 主线程const sharedBuffer = new SharedArrayBuffer(16);const intArray = new Int32Array(sharedBuffer);// 线程A写入Atomics.store(intArray, 0, 123);// 线程B读取const value = Atomics.load(intArray, 0);console.log(value); // 输出: 123

注意:必须使用Atomics API避免竞态条件。 

3. 事件通知(Emitter)
  • 机制:通过事件总线跨线程触发回调。
import emitter from \'@ohos.events.emitter\';// 线程A发布事件emitter.emit({ eventId: 1, // 事件ID priority: emitter.EventPriority.HIGH // 优先级}, { data: { key: \'value\' } // 事件数据});// 线程B订阅事件emitter.on(1, (eventData) => { console.log(`收到事件: ${eventData.data.key}`);});

三、线程与通信的选择策略

场景 推荐方案 原因 短时CPU密集型任务 TaskPool 自动管理,避免频繁创建线程 长时后台任务(如下载) Worker 隔离性强,崩溃不影响主线程 高性能计算(如音视频) Native线程 + 共享内存 减少序列化开销,提升速度 跨进程通信 RPC或分布式能力 鸿蒙专为跨设备设计

四、注意事项

1. 常见问题
  • 问题1:Worker文件路径错误 解决:确保路径为entry/ets/workers/文件名.ts

  • 问题2:TaskPool任务参数不可序列化 解决:仅传递基本类型、数组、普通对象。

2. 性能优化
  • 减少通信次数:合并多次postMessage为批量操作。
  • 共享内存:大数据传输优先用SharedArrayBuffer

 

艺术品交易