HarmonyOS 5.0应用开发——多线程Worker和@Sendable的使用方法

【高心星出品】

文章目录

      • 多线程Worker和@Sendable的使用方法
        • 开发步骤
        • 运行结果

多线程Worker和@Sendable的使用方法

Worker在HarmonyOS中提供了一种多线程的实现方式,它允许开发者在后台线程中执行长耗时任务,从而避免阻塞主线程并提高应用的响应性。

@Sendable 注解主要用于标记那些需要在多线程环境中共享的数据对象或函数。被 @Sendable 标记的对象或函数可以在不同的线程之间高效地传输数据,这主要得益于 ArkTS 的序列化和反序列化机制。

开发步骤

【案例需求】 接下来要实现一个案例,创建两个子线程,一个子线程负责数据求和,一个子线程负责数据相减,UI线程提供共享数据给这两个子线程,子线程运行结果返回给UI线程。

  • 创建两个worker。

    在ets/下创建一个workers目录,在该目录下创建worker。这两个worker负责接受UI线程传过来的数据,并且负责子线程运行实体,并将结果发送给UI线程。

在这里插入图片描述

在这里插入图片描述

  • addworker的代码
import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit.ArkTS';
import { Temp } from '../pages/Index';

const workerPort: ThreadWorkerGlobalScope = worker.workerPort;

/**
 * Defines the event handler to be called when the worker thread receives a message sent by the host thread.
 * The event handler is executed in the worker thread.
 *
 * @param event message data
 */
// 线程运行实体
function add(temp:Temp){
   let a=temp.a
  let b=temp.b
  temp.a+=5
  return a+b
}
// 子线程接受UI线程信息并处理
workerPort.onmessage = async (event: MessageEvents) => {
  if(event)
  {
    // 模拟线程睡眠2s
    await new Promise((resolve:(v:number)=>void)=>{
      setTimeout(()=>{resolve(10)},2000)
    })
    // 解析获取ui线程发送的数据
    let t=event.data as Temp
    // 子线程向UI线程发送消息
    workerPort.postMessage(add(t))
  }
};

/**
 * Defines the event handler to be called when the worker receives a message that cannot be deserialized.
 * The event handler is executed in the worker thread.
 *
 * @param event message data
 */
workerPort.onmessageerror = (event: MessageEvents) => {
};

/**
 * Defines the event handler to be called when an exception occurs during worker execution.
 * The event handler is executed in the worker thread.
 *
 * @param event error message
 */
workerPort.onerror = (event: ErrorEvent) => {
};
  • jianworker的代码
import { ErrorEvent, MessageEvents, ThreadWorkerGlobalScope, worker } from '@kit.ArkTS';
import { Temp } from '../pages/Index';

const workerPort: ThreadWorkerGlobalScope = worker.workerPort;

/**
 * Defines the event handler to be called when the worker thread receives a message sent by the host thread.
 * The event handler is executed in the worker thread.
 *
 * @param event message data
 */
// 线程运行实体
function jian(t:Temp){
  let a=t.a
  let b=t.b
  t.a-=5
  return Math.abs(a-b)
}
// 子线程接受UI线程的信息 并运行
workerPort.onmessage = async (event: MessageEvents) => {
  if(event){
    // 模拟线程睡眠2s
    await new Promise((resolve:(v:string)=>void)=>{
      setTimeout(()=>{
        resolve('a')
      },2000)
    })
    let t=event.data as Temp
    // 向UI线程发送消息
    workerPort.postMessage(jian(t))
  }
};

/**
 * Defines the event handler to be called when the worker receives a message that cannot be deserialized.
 * The event handler is executed in the worker thread.
 *
 * @param event message data
 */
workerPort.onmessageerror = (event: MessageEvents) => {
};

/**
 * Defines the event handler to be called when an exception occurs during worker execution.
 * The event handler is executed in the worker thread.
 *
 * @param event error message
 */
workerPort.onerror = (event: ErrorEvent) => {
};
  • Index.ets代码
import { MessageEvents, worker } from "@kit.ArkTS";

@Sendable
export class Temp {
  a: number
  b: number

  constructor(a: number, b: number) {
    this.a = a;
    this.b = b;
  }
}
@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  // UI线程和其他两个子线程共享的数据
  private temp = new Temp(10, 20)
  //创建了两个线程
  private addthread = new worker.ThreadWorker('entry/ets/workers/addworker.ets')
  private jianthread = new worker.ThreadWorker('entry/ets/workers/jianworker.ets')
  aboutToAppear(): void {
    // UI线程中接受两个子线程发送的信息
    this.addthread.onmessage = (event: MessageEvents) => {
      console.log('gxxt add ', event.data as number)
      console.log('gxxt 当前的temp值: ',JSON.stringify(this.temp))
    }
    this.jianthread.onmessage = (event: MessageEvents) => {
      console.log('gxxt jian ', event.data as number)
      console.log('gxxt 当前的temp值: ',JSON.stringify(this.temp))
    }
  }

  build() {
    Column({ space: 20 }) {
      Button('加线程')
        .width('60%')
        .onClick(() => {
          this.addthread.postMessageWithSharedSendable(this.temp)
        })
      Button('减线程')
        .width('60%')
        .onClick(() => {
          this.jianthread.postMessageWithSharedSendable(this.temp)
        })
    }
    .height('100%')
    .width('100%')
    .justifyContent(FlexAlign.Center)
  }
}

项目通过点击两个按钮启动两个线程,并将共享数据temp发送给两个子线程,两个子线程分别执行相加和相减,同时还更新共享数据的原始值,通过观察运算结果和共享数据的变化,我们能掌握worker的开发方式。

运行结果
02-28 09:10:59.798   3292-3292     A03d00/JSAPP     com.gxx.workdemo      I     gxxt add运算结果:  30
02-28 09:10:59.799   3292-3292     A03d00/JSAPP     com.gxx.workdemo      I     gxxt 当前的temp值:  {"a":15,"b":20}
02-28 09:11:04.877   3292-3292     A03d00/JSAPP     com.gxx.workdemo      I     gxxt jian运算结果  5
02-28 09:11:04.877   3292-3292     A03d00/JSAPP     com.gxx.workdemo      I     gxxt 当前的temp值:  {"a":10,"b":20}

刚一开始进行运算的时候add线程面对的a为10,b为20,计算结果为30,add线程同时a=a+5操作,所以此时UI线程得到的a为15;然后jian线程运行结果为|15-20|,jian线程同时a=a-5,所以此时UI线程得到的a为10.

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《深度学习实战》第3集:循环神经网络(RNN)与序列建模

第3集:循环神经网络(RNN)与序列建模 引言 在深度学习领域,处理序列数据(如文本、语音、时间序列等)是一个重要的研究方向。传统的全连接网络和卷积神经网络(CNN)难以直接捕捉序列中…

10.【线性代数】—— 四个基本子空间

十、 四个基本子空间 1. 列空间 C ( A ) C(A) C(A) in R m R^m Rm2. 零空间 N ( A ) N(A) N(A) in R n R^n Rn3. 行空间 C ( A T ) C(A^T) C(AT) in R n R^n Rn4. 左零空间 N ( A T ) N(A^T) N(AT) in R m R^m Rm综述5. 新的向量空间 讨论矩阵 A m ∗ n A_{m*n} Am∗n​…

Windows上使用go-ios实现iOS17自动化

前言 在Windows上运行iOS的自动化,tidevice对于iOS17以上并不支持,原因是iOS 17 引入新通信协议 ‌RemoteXPCQUIC‌,改变了 XCUITest 的启动方式。 一、go-ios的安装 1、安装命令:npm i go-ios 2、安装完成后输入命令which io…

CBAM注意力机制详解与实现

前言: 在深度学习领域,注意力机制已成为提升模型性能的重要手段之一。CBAM(Convolutional Block Attention Module)作为一种轻量级且高效的注意力机制,被广泛应用于各种卷积神经网络中。 一、CBAM注意力机制概述 1.…

GCN从理论到实践——基于PyTorch的图卷积网络层实现

Hi,大家好,我是半亩花海。图卷积网络(Graph Convolutional Network, GCN)是一种处理图结构数据的深度学习模型。它通过聚合邻居节点的信息来更新每个节点的特征表示,广泛应用于社交网络分析、推荐系统和生物信息学等领…

给虚拟机配置IP

虚拟机IP这里一共有三个地方要设置,具体说明如下: (1)配置vm虚拟机网段 如果不进行设置,每次启动机器时都可能是随机的IP,不方便我们后续操作。具体操作是:点击编辑→虚拟网络编辑器 选择VMne…

【免费】YOLO[笑容]目标检测全过程(yolo环境配置+labelimg数据集标注+目标检测训练测试)

一、yolo环境配置 这篇帖子是我试过的,非常全,很详细【cudaanacondapytorchyolo(ultralytics)】 yolo环境配置 二、labelimg数据集标注 可以参考下面的帖子,不过可能会出现闪退的问题,安装我的流程来吧 2.1 labelimg安装 label…

mapbox基础,使用geojson加载heatmap热力图层

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️heatmap热力图层样式二、🍀使用geojs…

Python 课堂点名桌面小程序

一、场景分析 闲来无事,老婆说叫我开发一个课堂点名桌面小程序,给她在课堂随机点名学生问问题。 人生苦短,那就用 Python 给她写一个吧。 二、依赖安装 因为要用到 excel,所以安装两个依赖: pip install openpyxl…

蓝桥杯 路径之谜

路径之谜 题目描述 小明冒充 XX 星球的骑士,进入了一个奇怪的城堡。 城堡里边什么都没有,只有方形石头铺成的地面。 假设城堡地面是 nnnn 个方格。如下图所示。 按习俗,骑士要从西北角走到东南角。可以横向或纵向移动,但不能斜着走…

在鸿蒙HarmonyOS手机上安装hap应用

一、下载工具 安装hap包需要用到小工具 。 二、解压到目录后,进入该文件夹,打开命令行,如下图 三、将下载好的hap包放入刚才解压的文件夹内(假设hap包文件名为app.hap) 四、连接好手机和电脑,手机需要打…

Android APK组成编译打包流程详解

Android APK(Android Package)是 Android 应用的安装包文件,其组成和打包流程涉及多个步骤和文件结构。以下是详细的说明: 一、APK 的组成 APK 是一个 ZIP 格式的压缩包,包含应用运行所需的所有文件。解压后主要包含以…

自然语言处理:词频-逆文档频率

介绍 大家好,博主又来给大家分享知识了。本来博主计划完成稠密向量表示的内容分享后,就开启自然语言处理中文本表示的讲解。可在整理分享资料的时候,博主发现还有个知识点,必须得单独拎出来好好说道说道。 这就是TF-IDF&#xf…

esp8266 rtos sdk开发环境搭建

1. 安装必要的工具 1.1 安装 Git Git 用于从远程仓库克隆代码,你可以从Git 官方网站下载 Windows 版本的安装程序。安装过程中可保持默认设置,安装完成后,在命令提示符(CMD)或 PowerShell 中输入git --version&#…

pytest下放pytest.ini文件就导致报错:ERROR: file or directory not found: #

pytest下放pytest.ini文件就导致报错:ERROR: file or directory not found: # 如下: 项目文件目录如下: pytest.ini文件内容: [pytest] addopts -v -s --alluredir ./allure-results # 自动添加的命令行参数:# -…

Blender调整最佳渲染清晰度

1.渲染采样调高 512 2.根据需要 开启AO ,开启辉光 , 开启 屏幕空间反射 3.调高分辨率 4096x4096 100% 分辨率是清晰度的关键 , 分辨率不高 , 你其他参数调再高都没用 4.世界环境开启体积散射 , 可以增强氛围感 5.三点打光法 放在模型和相机45夹角上 白模 白模带线条 成品

Vllm进行Qwen2-vl部署(包含单卡多卡部署及爬虫请求)

1.简介 阿里云于今年9月宣布开源第二代视觉语言模型Qwen2-VL,包括 2B、7B、72B三个尺寸及其量化版本模型。Qwen2-VL具备完整图像、多语言的理解能力,性能强劲。 相比上代模型,Qwen2-VL 的基础性能全面提升,可以读懂不同分辨率和…

xr-frame 3D Marker识别,扬州古牌坊 3D识别技术稳定调研

目录 识别物体规范 3D Marker 识别目标文件 map 生成 生成任务状态解析 服务耗时: 对传入的视频有如下要求: 对传入的视频建议: 识别物体规范 为提高Marker质量,保证算法识别效果,可参考Marker规范文档 Marker规…

Windows环境下SuperMapGIS 11i 使用达梦数据库

1. 环境介绍: 1.1. 操作系统: windows server 2019 1.2. GIS 软件: 1.2.1. GIS 桌面 supermap-idesktopx-11.3.0-windows-x64-bin 下载链接:SuperMap技术资源中心|为您提供全面的在线技术服务 安装教程:绿色版&…

redis的下载和安装详解

一、下载redis安装包 进入redis官网查看当前稳定版本: https://redis.io/download/发现此时的稳定版本是6.2.4, 此时可以去这个网站下载6.2.4稳定版本的tar包。 暂时不考虑不在windows上使用redis,那样将无法发挥redis的性能 二、上传tar…