鸿蒙HarmonyOS应用开发之使用Node-API接口进行线程安全开发

场景介绍

napi_create_threadsafe_function是Node-API接口之一,用于创建一个线程安全的JavaScript函数。主要用于在多个线程之间共享和调用,而不会出现竞争条件或死锁。例如以下场景:

  • 异步计算:如果需要进行耗时的计算或IO操作,可以创建一个线程安全的函数,将计算或IO操作放在另一个线程中执行,避免阻塞主线程,提高程序的响应速度。

  • 数据共享:如果多个线程需要访问同一份数据,可以创建一个线程安全的函数,确保数据的读写操作不会发生竞争条件或死锁等问题。

  • 多线程编程:如果需要进行多线程编程,可以创建一个线程安全的函数,确保多个线程之间的通信和同步操作正确无误。

使用示例

  1. 在Native入口定义线程安全函数。
struct CallbackData {napi_threadsafe_function tsfn;napi_async_work work;
};static napi_value StartThread(napi_env env, napi_callback_info info)
{size_t argc = 1;napi_value jsCb = nullptr;CallbackData *callbackData = nullptr;napi_get_cb_info(env, info, &argc, &jsCb, nullptr, reinterpret_cast<void **>(&callbackData));// 创建一个线程安全函数napi_value resourceName = nullptr;napi_create_string_utf8(env, "Thread-safe Function Demo", NAPI_AUTO_LENGTH, &resourceName);napi_create_threadsafe_function(env, jsCb, nullptr, resourceName, 0, 1, callbackData, nullptr, callbackData, CallJs, &callbackData->tsfn);// 创建一个异步任务napi_create_async_work(env, nullptr, resourceName, ExecuteWork, WorkComplete, callbackData,&callbackData->work);// 将异步任务加入到异步队列中napi_queue_async_work(env, callbackData->work);return nullptr;
}
  1. 在工作线程中调用ExecuteWork,并执行线程安全函数。
static void ExecuteWork(napi_env env, void *data)
{CallbackData *callbackData = reinterpret_cast<CallbackData *>(data);std::promise<std::string> promise;auto future = promise.get_future();napi_call_threadsafe_function(callbackData->tsfn, &promise, napi_tsfn_nonblocking);try {auto result = future.get();// OH_LOG_INFO(LOG_APP, "XXX, Result from JS %{public}s", result.c_str());} catch (const std::exception &e) {// OH_LOG_INFO(LOG_APP, "XXX, Result from JS %{public}s", e.what());}
}
  1. 在JS线程执行异步回调函数。
static napi_value ResolvedCallback(napi_env env, napi_callback_info info)
{void *data = nullptr;size_t argc = 1;napi_value argv[1];if (napi_get_cb_info(env, info, &argc, argv, nullptr, &data) != napi_ok) {return nullptr;}size_t result = 0;char buf[32] = {0};napi_get_value_string_utf8(env, argv[0], buf, 32, &result);reinterpret_cast<std::promise<std::string> *>(data)->set_value(std::string(buf));return nullptr;
}static napi_value RejectedCallback(napi_env env, napi_callback_info info)
{void *data = nullptr;if (napi_get_cb_info(env, info, nullptr, nullptr, nullptr, &data) != napi_ok) {return nullptr;}reinterpret_cast<std::promise<std::string> *>(data)->set_exception(std::make_exception_ptr(std::runtime_error("Error in jsCallback")));return nullptr;
}static void CallJs(napi_env env, napi_value jsCb, void *context, void *data)
{if (env == nullptr) {return;	}napi_value undefined = nullptr;napi_value promise = nullptr;napi_get_undefined(env, &undefined);napi_call_function(env, undefined, jsCb, 0, nullptr, &promise);napi_value thenFunc = nullptr;if (napi_get_named_property(env, promise, "then", &thenFunc) != napi_ok) {return;}napi_value resolvedCallback;napi_value rejectedCallback;napi_create_function(env, "resolvedCallback", NAPI_AUTO_LENGTH, ResolvedCallback, data,&resolvedCallback);napi_create_function(env, "rejectedCallback", NAPI_AUTO_LENGTH, RejectedCallback, data,&rejectedCallback);napi_value argv[2] = {resolvedCallback, rejectedCallback};napi_call_function(env, promise, thenFunc, 2, argv, nullptr);
}
  1. 任务执行完成后,进行资源清理回收。
static void WorkComplete(napi_env env, napi_status status, void *data)
{CallbackData *callbackData = reinterpret_cast<CallbackData *>(data);napi_release_threadsafe_function(callbackData->tsfn, napi_tsfn_release);napi_delete_async_work(env, callbackData->work);callbackData->tsfn = nullptr;callbackData->work = nullptr;
}
  1. 模块初始化以及ArkTS侧调用接口。
// 模块初始化
static napi_value Init(napi_env env, napi_value exports) {CallbackData *callbackData = new CallbackData(); // 可在线程退出时释放napi_property_descriptor desc[] = {{"startThread", nullptr, StartThread, nullptr, nullptr, nullptr, napi_default, callbackData},};napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);return exports;
}// ArkTS侧调用接口
import nativeModule from 'libentry.so'; // 通过import的方式,引入Native能力let callback = (): Promise<string> => {return new Promise((resolve) => {setTimeout(() => {resolve("string from promise");}, 5000);});}nativeModule.startThread(callback);

为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙开发学习手册》:

如何快速入门:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH

鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH

1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Scala介绍与环境搭建

Scala环境搭建与介绍 一、Scala环境搭建 1、环境准备与下载 2、验证Scala 3、IDEA新建项目&#xff0c;配置Scala&#xff0c;运行Hello world 二、Scala介绍 1、Scala 简介 2、Scala 概述 一、Scala环境搭建 1、环境准备与下载 JDK1.8 Java Downloads | Oracle 下载需求版本…

如何将python项目转变成deb安装包

先将python项目转变成可执行文件 1. 首先确保你的python项目可以正常执行 2.安装pyinstaller模块&#xff0c;pip install pyinstaller -i Simple Index 3.确定好你的项目的文件入口&#xff0c;也就是运行的文件.py 4. 开始打包成单文件&#xff0c;pyinstaller -F <第…

美团春招内幕揭秘:2024最全面Spring CORS面试题解析,跨域问题大师级指南!

随着现代Web应用越来越多地采用前后端分离的架构&#xff0c;跨域资源共享&#xff08;CORS&#xff09;成为了Web开发中不可或缺的一部分。对于构建复杂、响应迅速的Web应用&#xff0c;了解并正确实施CORS策略是确保应用安全、高效运行的关键。美团&#xff0c;作为中国领先的…

STM32学习笔记(6_7)- TIM定时器的编码器接口原理

无人问津也好&#xff0c;技不如人也罢&#xff0c;都应静下心来&#xff0c;去做该做的事。 最近在学STM32&#xff0c;所以也开贴记录一下主要内容&#xff0c;省的过目即忘。视频教程为江科大&#xff08;改名江协科技&#xff09;&#xff0c;网站jiangxiekeji.com 现在开…

【Java程序设计】【C00374】基于(JavaWeb)Springboot的社区疫情管理系统(有论文)

TOC 博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c;博客中有上百套程序可供参考&#xff0c;欢迎共同交流学习。 项目简介 项目获取 &#x1f345;文末点击卡片…

教学软件哪个好?这个一站式智慧教学系统值得推荐!

过去培训机构老师授课的场景主要在线下&#xff0c;可以使用大屏幕 PPT 来完成培训的交付&#xff0c;而现在随着数字化基础设施的完善&#xff0c;同时为了尽可能覆盖更多的人&#xff0c;依赖线下的培训场景也逐步转移到线上来完成&#xff0c;因此也对在线教学工具产生了需…

服务器硬件基础知识详解

服务器硬件基础知识涵盖了多个关键组件及其功能&#xff0c;以下是详细的介绍&#xff1a; 一. 处理器&#xff08;CPU&#xff09;&#xff1a; 处理器&#xff08;CPU&#xff0c;Central Processing Unit&#xff09;&#xff0c;即中央处理器&#xff0c;是电子计算机的主…

【前端学习——css篇】3.隐藏元素的方法

https://github.com/febobo/web-interview 3.隐藏元素的方法 diplay:none; 元素在页面消失&#xff0c;并且不占据页面空间 opacity:0; 设置元素透明度&#xff0c;仅元素不可见&#xff0c;占用空间 visibility:hidden; 元素不可见&#xff0c;占据页面空间&#xff0c;无…

如何用OBD创建OceanBase集群

OBD创建集群的方式适用于迅速搭建集群以进行测试工作。但是在涉及线上环境的部署时&#xff0c;推荐采用OCP进行集群的创建与管理。 有关OBD 的一些详细信息&#xff0c;可以去 github 了解&#xff0c;GitHub - oceanbase/obdeploy: A deployer and package manager for Ocea…

东方博宜 1521. 计算分数加减表达式的值

东方博宜 1521. 计算分数加减表达式的值 #include<iostream> #include<iomanip> using namespace std; int main() {double n ;cin >> n ;double sum ;sum 0.0 ;double j ;j 1.0 ;for (int i 1 ; i < n ; i){sum 1.0 / i * j ; j * -1 ;}cout <…

C++进阶学习(3)类类型转换

文章目录 一、类类型转换1.构造函数构造2.类型转换函数 一、类类型转换 数据类型转换在程序编译时或在程序运行实现 基本类型 ←→ 基本类型 基本类型 ←→ 类类型 类类型 ←→ 类类型 类对象的类型转换可由两种方式说明&#xff1a; 构造函数 转换函数 称为用户定义的类型转…

计算机网络01-20

计算机网络01-20 以下是本文参考的资料 欢迎大家查收原版 本版本仅作个人笔记使用1、OSI 的七层模型分别是&#xff1f;各自的功能是什么&#xff1f;2、说一下一次完整的HTTP请求过程包括哪些内容&#xff1f;孤单小弟 —— HTTP真实地址查询 —— DNS指南好帮手 —— 协议栈可…

Docker进阶:Docker Swarm —弹性伸缩调整服务的副本数量

Docker进阶&#xff1a;Docker Swarm —弹性伸缩调整服务的副本数量 1、 创建一个Nginx服务&#xff08;Manager节点&#xff09;2、查看服务状态&#xff08;Manager节点&#xff09;3、测试访问&#xff08;Worker节点&#xff09;4、查看服务日志&#xff08;Manager节点&am…

详解智慧路灯杆网关的集中供电能力

智慧路灯杆网关是智慧杆物联网系统中不可或缺的设备。智慧杆网关不仅可以作为杆载设备与云平台、设备与设备之间的桥梁&#xff0c;促进数据的无缝传输&#xff0c;而且还能提供高效的能源管理和供电功能。 BMG8200系列交流型智慧路灯杆网关就集成了强大的供电能力&#xff0c;…

浅析扩散模型与图像生成【应用篇】(十三)——PITI

13. Pretraining is All You Need for Image-to-Image Translation 该文提出一种基于预训练扩散模型的图像转换方法&#xff0c;称为PITI。其思想并不复杂&#xff0c;就是借鉴现有视觉和NLP领域中常见的预训练方法&#xff0c;考虑预先在一个大规模的任务无关数据集上对扩散模…

nginx学习记录-反向代理

1. 反向代理 一个简单的反向代理示意图如下&#xff1a; 我们的PC需要访问内网资源时&#xff0c;网关路由不直接将请求转发给内网的应用服务器&#xff0c;而是通过nginx服务器进行代理转发&#xff0c;转发到应用服务器上&#xff0c;应用服务器响应请求后会将响应数据再通过…

hdlbits系列verilog解答(Mux256to1v)-64

文章目录 一、问题描述二、verilog源码三、仿真结果一、问题描述 本节我们创建一个 4 位宽、256:1 的多路复用器。256 个 4 位输入全部封装到单个 1024 位输入向量中。sel=0 应选择位 in[3:0] ,sel=1 选择位 in[7:4] ,sel=2 选择位 in[11:8] ,以此类推。 模块声明 module…

AJAX~

概念:AJAX(Asynchronous JavaScript And XML):异步的JavaScript和XML AJAX作用&#xff1a; 1.与服务器进行数据交换:通过AJAX可以给服务器发送请求&#xff0c;并获取服务器响应的数据 使用了AJAX和服务器进行通信&#xff0c;就可以使用HTMLAJAX来替换JSP页面了 2&#xf…

【MATLAB源码-第170期】基于matlab的BP神经网络股票价格预测GUI界面附带详细文档说明。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 基于BP神经网络的股票价格预测是一种利用人工神经网络中的反向传播&#xff08;Backpropagation&#xff0c;简称BP&#xff09;算法来预测股票市场价格变化的技术。这种方法通过模拟人脑的处理方式&#xff0c;尝试捕捉股票…

欧美用户真实反馈!他们为什么选择爱可声助听器?

在竞争激烈的助听器市场上&#xff0c;爱可声助听器在欧美地区赢得了广泛的认可和好评。为什么越来越多的欧美用户选择爱可声助听器呢&#xff1f; 约翰&#xff0c;纽约的退休音乐教师 约翰是一位热爱音乐的退休音乐教师&#xff0c;他的一生都与音乐相伴&#xff0c;从年轻…