解决webassembly pthread 子线程调用主线程js问题

news2024/10/5 17:24:54

解决webassembly pthread 子线程调用主线程js问题

背景:

web端项目做了一段时间后,我们需求是加载工程是异步的,主线程会调用wasm方法,wasm内部用pthread创建出来线程,然后在这个线程里边处理任务,处理完成后,需要通知主线程加载完成了,但是这个通知怎么实现,花了一些时间。下边就是之前整理的方案

具体调用逻辑如下图所示:

 

我们知道web端work相关通信是 通过postmessage,onmessage实现的,接下来尝试各种方案

方案一:

Webassembly 我们用c或者c++创建的线程,编译器最终把它转成work,也就是说我们能不能通过work 之间通信解决这个问题呢,我想是可以的。但是十分不方便,因为编译在编译后生成浇水js代码,以及创建线程需要work的浇水代码,我们要改动浇水里边的通信方式, 在次编译后又给覆盖了,极其不方便。

 

从上图也可以看出来,改好后,重新编译代码又给覆盖了。

方案二

js MessageChannel   也可以实现work之间通信。

Instance properties

MessageChannel.port1 Read only

Returns port1 of the channel.

MessageChannel.port2 Read only

Returns port2 of the channel.

具体用法网上有很多,work 持有MessageChange port2, 主线程池游port1,两者可以通过port的postMessage与onMessage进行通信,这种方法在js层面比较方便,但是我们这个要求是wasm里边的work,

主线程怎么把port给传到子线程work中,都比较费力,显然也不是好的方案

方案三

主线程轮训的方式,也就是我们主线程调用LoadProject后,我们返回一个uniqueid, 主线程设置setInterval,开启个定时任务,每隔一定时间查询下uniqueid 代码的任务是否完成,原理是uniqueid关联一个future,可以通过future去实现任务是否完成的查询。

很显然这种方式是可以的,但是需要额外的浪费主线程的一点点性能,

方案四

有没有直接通过调用一个c方法直接把方法抛到主线程去执行的呢,这也是我所期望的。为了实现这个目标我约的emscripten 里边的源码,找到了一些蛛丝马迹,觉得应该是有接口直接调用的。

在test_pthread_proxying.c这个文件中看到了,emscripten_proxy_async 这个方法,接着我就去看下这个方法对应的实现,

C++
int emscripten_proxy_async(em_proxying_queue* q,
                           pthread_t target_thread,
                           void (*func)(void*),
                           void* arg) {
  assert(q != NULL);
      pthread_mutex_lock(&q->mutex);
      em_task_queue* tasks = get_or_add_tasks_for_thread(q, target_thread);
      pthread_mutex_unlock(&q->mutex);
      if (tasks == NULL) {
        return 0;
      }
      pthread_mutex_lock(&tasks->mutex);
      int enqueued = em_task_queue_enqueue(tasks, (task){func, arg});
      pthread_mutex_unlock(&tasks->mutex);
      if (!enqueued) {
        return 0;
      }
  return 1;
}
void em_task_queue_execute(em_task_queue* queue) {
      queue->processing = 1;
      pthread_mutex_lock(&queue->mutex);
      while (!em_task_queue_is_empty(queue)) {
        task t = em_task_queue_dequeue(queue);
        // Unlock while the task is running to allow more work to be queued in
        // parallel.
        pthread_mutex_unlock(&queue->mutex);
        t.func(t.arg);
        pthread_mutex_lock(&queue->mutex);
      }
      pthread_mutex_unlock(&queue->mutex);
      queue->processing = 0;
}

通过上边源码也可以看的出来target_thread,是目标线程的id,可以通过pthread_self()获取, func与args需要执行函数,与args参数,

首先会把根据target_thread 把所在线程的tasks(任务队列取出来),然后把我们的func加进去, 所在线程会调用emscripten_proxy_execute_queue 来执行任务队列,因此这种方式满足了我们的需求。

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

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

相关文章

园区智慧导览地图软件,智慧工厂导航定位怎么解决方案的

智慧工厂导航定位怎么解决方案的地图新基建是行业的核心数字基础需求之一,行业内中已构建了较为完整的城市级地理信息系统。园区管理涉及众多方面,因此园区的智慧信息化建设至关重要,需求越来越广泛。在智慧园区中,基于园区的电子…

【C++类和对象】类和对象(上){初识面向对象,类的引入,类的定义,类的访问限定符,封装,类的作用域,类的实例化,类对象模型,this指针}

一、面向过程和面向对象初步认识 C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。 C是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。…

瑞吉外卖:项目介绍和环境搭建

文章目录 软件开发基础软件开发流程角色分工软件环境 瑞吉外卖项目介绍项目介绍开发流程技术选型功能架构角色 环境搭建 软件开发基础 软件开发流程 需求分析:产品原型(大体结构、页面、功能等)和需求规格说明书设计:产品文档、…

TCP/UDP的头部字段细节

目录 TCP头部字段 一、源端口目的端口(各占2字节) 二、序列号(4字节) 三、确认号(4字节) 四、数据偏移(4位) 五、保留位(6位) 六、六个控制位&#xff…

『pyqt5 从0基础开始项目实战』09.本地数据配置文件的保存与读取之txt类型(保姆级图文)

目录 导包和框架代码绑定按钮点击事件在dialog中编写代理配置弹窗UI和功能实现代理配置弹窗UI方法完整代码main.pythreads.pydialog.py 总结 欢迎关注 『pyqt5 从0基础开始项目实战』 专栏,持续更新中 欢迎关注 『pyqt5 从0基础开始项目实战』 专栏,持续…

Jenkins 实现自动化部署

安装 windows下安装:https://blog.csdn.net/u014641168/article/details/130286547 linux下安装:https://blog.csdn.net/u014641168/article/details/130282439 Jenkins支持JDK1.8对应版本说明:https://blog.csdn.net/u014641168/article/…

STM32 学习笔记_3 程序编写基础;arm 内核架构

程序编写基础 Keil 编辑器设置 抛开 tab 和空格哪个好看不谈,不同编译器设置格式不同,空格比较保险。 用户关键字:打出来的时候会高亮。 代码提示:(symbols after 是几个字符后开始提示关键字的意思) 以上…

6、索引的数据结构

3.3 常见的索引概念 索引按照物理实现方式,索引可以分为 2 种:聚簇和非聚簇索引 1、聚簇索引 5、索引的代价 空间上的代价 每建立一个索引都要为它建立一棵B树,每一棵B树的每一个节点都是一个数据页,一个页默认会占用 16KB 的存…

jsp827+java心理测评管理系统dzkfB4程序j2EE+mysql

现代社会的大学生是21世纪的主人,他们不仅需要具有为社会做贡献的真才实学,更需要健康的心理。大学生的身心健康,人格健全和谐发展是他们学习的需要,是社会对未来参与者素质的要求。 1.系统登录:系统登录是…

thinkphp:插入数据到数组

一、插入数据到数组首位(array_unshift),这里全用空值进行插入 $array [a,b,c]; //在首位加入一个空值 array_unshift($array ,); //将数组输出 print_r($array); 输出结果: 二、插入数据到数组末尾(array_push&…

docker安装kafka,并集成springboot进行测试

大家好,今天我们开始学习kafka中间件,今天我们改变一下策略,不刷视频学习,改为实践学习,在网上找一些案例功能去做,来达到学习实践的目的。 首先,是安装相关组件。 1. docker安装安装 1.1 yu…

深度学习中的各种不变性

不变性 平移不变性(Translation Invariance)旋转不变性(Ratation Invariance)尺度不变性(Size Invariance)光照不变性(Illumination Invariance)仿射不变性(Affine Invar…

PS学习记录-图像【像素】与【分辨率】的说明

我们经常能在图片的属性中看到 1920像素x1080像素 (老司机在视频文件中也经常看到~) 这就是我们常说的图片分辨率,以下是我学习整理的关于像素、分辨率的资料。 注意: 图像分辨率是针对【位图】的,图片分辨率决定了…

记录-JS简单实现购物车图片局部放大预览效果

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 一、实现效果 二、代码实现 代码不多&#xff0c;先看一下 HTML 里面结构很简单&#xff0c;初始化 MagnifyingGlass 对象来关联一个 IMG 标签来实现放大。 <!DOCTYPE html> <html> <h…

做一个网站需要多少个技术人员?

作为互联网从业者&#xff0c;这么多年来经常会碰到一个灵魂拷问&#xff0c;那就是“为什么一个网站需要那么多技术人员&#xff1f;”&#xff0c;尤其是提问者如果再追问一下“听说几个相关专业的学生一个课程的作业就是开发一个网站或者app&#xff0c;那为什么现在主流的网…

C++ | 认识标准库string和vector

本文概要 本篇文章主要介绍C的标准库类型string和vector&#xff0c;文中描述和代码示例很详细&#xff0c;看完即可掌握&#xff0c;感兴趣的小伙伴快来一起学习吧。 &#x1f31f;&#x1f31f;&#x1f31f;个人简介 &#x1f31f;&#x1f31f;&#x1f31f; ☀️大家好&a…

stable diffusion安装从0到1总结:包括遇到的坑和步骤

注&#xff1a;最低电脑配置&#xff1a;8G Vram16G RAM30G磁盘空间以上&#xff0c;20系列显卡及以上&#xff0c;windows>linux>macos。 文件可以不放在系统盘。举个例子&#xff1a;安装在D盘&#xff0c;在D盘创建一个StableDiffusion文件夹。下载下面文件: 1.下载…

为什么实现 API 最佳实践需要重新考虑安全性

随着应用程序编程接口 (API) 的使用与日俱增&#xff0c;实现和维护有效安全性的挑战从未像现在这样大。 由于缺乏管理 API 的单一标准&#xff0c;这意味着团队不能仅依靠工具来解决安全问题&#xff0c;因此这一挑战变得更加严峻。没有任何一种产品可以解决 API 环境的每种…

pg编码相关问题梳理

Lightdb/PG 编码相关问题梳理 之前在通过SQL文件导入数据时&#xff0c;报&#xff1a;ERROR: invalid byte sequence for encoding "EUC_CN"错误。然后就梳理了一下编码相关问题&#xff0c;这边记录一下。涉及到如下两种类型的报错&#xff1a; ERROR: invalid b…

电脑如何还原系统?这样做可以快速解决!

案例&#xff1a;我的电脑系统出问题了&#xff0c;怎么还原&#xff1f; 【我的电脑用了好几年了&#xff0c;最近它的系统出现了一些问题&#xff0c;我想还原电脑系统。有没有知道电脑系统如何还原&#xff1f;蹲一个简单的解决方法&#xff01;】 随着电脑使用时间的增加…