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

2023-05-16

解决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 来执行任务队列,因此这种方式满足了我们的需求。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

解决webassembly pthread 子线程调用主线程js问题 的相关文章

  • Ubuntu20.04软件安装大全

    目录 Ubuntu20 04 软件安装大全前言1 Windows和Ubuntu双系统安装1 1 下载Ubuntu系统镜像1 2 磁盘分区1 3 GPT分区安装Ubuntu1 4 系统完成后的一些设置1 5 遇到的一些小bug 2 换源2 1
  • 基于Nginx构建七牛云CDN静态资源加速

    创建七牛云账号 七牛云 进入管理控制台创建对象存储 3 配置nginx 使用nginx rewrite 的重定向功能进行转发到七牛云 server listen 80 server name test com 你的域名 location g
  • ChinaSkills-网络系统管理(2021年全国职业院校技能大赛A-1 模块 A:Linux 环境 真题 )

    前言 随着近年国家对技术性的比赛越来越重视 xff0c 各类技能大赛举办的相较正规 xff0c 这类大赛一般是在专科中专等技术性高中等院校中选拔优秀人才 xff0c 并且技能大赛的一等奖选手将有资格保送本科 xff0c 希望一些有能力的专科
  • Cannot resolve symbol 解决方案汇总(6种解决方案)

    Cannot resolve symbol 39 xxx 39 是比较常见一种错误 xff0c 以下整理常见的六种解决方案 xff0c 第六种会说明一下造成的原因和如何避免 方案一 检查一下pom文件依赖是否正常 xff0c 如不正常刷新m
  • 踩坑指南!import cv2出错怎么办?

    好久没有更新 xff0c 最近代码相关问题看的比较少 xff0c 有时候忙着debug就忘记了记录 xff0c 反思一下 背景 xff1a 在提取视频帧序列的时候用到了opencv包 xff0c 结果运行出错 解决 xff1a 经过查找资料
  • 最小生成树——北极通讯网络

    问题 B 北极通讯网络 时间限制 1 Sec 内存限制 128 MB 提交 17 解决 7 提交 状态 讨论版 命题人 add xiezhenghao 题目描述 北极的某区域共有n座村庄 xff08 1 n 500 xff09 xff0c
  • c++ 判定子类是否重写父类虚方法

    背景 xff1a 在做业务的时候 xff0c 有时会蹦到一个业务逻辑 xff0c 如果子类重写父类方法 xff0c 就调用 xff0c 如果没重写就不调用它 xff0c 这个逻辑在大量子类集成同一个父类的 xff0c 会节约一点点性能 xf
  • Windows | RDPWrap 远程桌面登录增强工具 (解决win10/11家庭版无法使用远程桌面 + 支持多人同时登录)

    一 前言 Windows远程桌面 Windows远程桌面是一种技术 xff0c 允许用户从远程位置访问和控制在另一个地方的Windows计算机 它可以帮助管理员和其他用户实现远程管理 技术支持和协同工作等操作 使用Windows远程桌面 x
  • 字符串匹配(java)

    字符串匹配 字符串匹配可以用到蛮力法 对于字符串s和t xff0c 若t是s的子串 xff0c 返回t在s中的位置 xff08 t的首字符在s中的下标 xff09 xff0c 否则返回 1 采用的是穷举法 xff0c 从s的第一个字符开始查
  • 警告:Establishing SSL connection without server's identity verification is not recommended

    解决方法 那问题来了 xff0c SSL是什么 xff1f SSL xff08 Secure Socket Layer xff1a 安全套接字层 xff09 利用数据加密 身份验证和消息完整性验证机制 xff0c 为基于TCP等可靠连接的应
  • NestJs-项目创建

    NestJs Nest js 用于构建高效且可伸缩的服务端应用程序的渐进式 Node js 框架 项目创建 构建工具 可以使用 npm yarn pnpm进行包管理 xff0c 但议使用pnpm建议安装nrm镜像源管理工具 xff0c 可以
  • C++ 字符串格式化

    使用snprintf格式化字符串使用boost format格式化字符串使用stringstream格式化字符串 具体示例 使用snprintf格式化字符串 span class token macro property span clas
  • 玩客云 一个百元级的微型服务器

    前言 下面这段基本是copy的 xff0c 就是图个完整 xff0c 不要觉得奇怪哈 玩客云是一款前些年很火的矿机 xff0c 曾经在官网售卖 xffe5 599 xff0c 现在已经沦落到 xffe5 45包邮的田地了 当然这边一般有两种
  • OpenStack双节点部署—M Manila(共享文件系统服务)

    Manila安装 一 数据库配置二 创建服务凭证和API端点三 安装并配置Heat四 启动服务并设置开机自启 一 数据库配置 Controller节点 mysql span class token operator span uroot s
  • Dockerfile简介

    1 什么是dockerfile Dockerfile是一个包含用于组合映像的命令的文本文档 可以使用在命令行中调用任何命令 Docker通过读取Dockerfile中的指令自动生成映像 docker build命令用于从Dockerfile
  • 论文阅读笔记1:EKT: Exercise-aware Knowledge Tracing for Student Performance Prediction

    该篇论文于2019年在IEEE发表 xff0c 作者为 xff1a Qi Liu Zhenya Huang Yu Yin Enhong Chen Hui Xiong Yu Su and Guoping Hu 等 知识追踪 xff08 Kno
  • 树莓派 同时使用有线和无线网卡

    树莓派同时使用有线和无线 使能双网卡待机 添加路由使用规范 备注 192 168 1 0 表明所有以192 168 1开始的网段 都将从后面的设备发送相应的数据 使能双网卡待机 Linux通过设置默认的网络信息实现双网卡待机 设置方法如下
  • c++20 协程本质

    c 43 43 20 协程本质 背景 xff1a 最近因项目关系 xff0c web端 xff0c js异步调用 xff0c 发现跟本门的C 43 43 20 还是有些不一样的 xff0c 本文主要从另外一个角度来看 什么是协程 协程是能暂
  • Manjaro 21安装搜狗输入法

    Manjaro 21安装搜狗输入法 文章目录 Manjaro 21安装搜狗输入法安装输入法Step 1 打开 96 Manjaro Hello 96 点击 96 Application 96 Step 2 切换语言到 96 Chinese
  • Unicode控制字符

    Unicode控制字符 一 前言 在所有主要的Web浏览器中内存中的字符顺序 xff08 逻辑 xff09 与它们显示的顺序 xff08 可视 xff09 是不同的 Unicode 定义了它其中每个字符的方向属性 xff0c 浏览器应用的一

随机推荐