首页 > 解决方案 > WebAssembly 中的多线程

问题描述

如果您回答我关于 WebAssembly 多线程的问题,我将不胜感激。我想用 2 个线程(主线程和一个辅助线程)实现代码,这样就有一个全局变量用作辅助线程中的计数器变量,并在循环中递增它。和主线程,读取计数器变量数量,一次在运行指令之前和一次之后(测量完成该指令所需的时间)。我已经实现了这段代码:


#include "pthread.h"
#include <stdio.h>
#include <unistd.h>
#include<chrono>

int i;
int counter;

void* timerfunction( void *ptr)
{
  printf ("Thread Timer!\n");
  //cout<<"Thread Timer!"<<endl;
  while(1)
  {
    counter=counter+1;
  }
  pthread_exit("The thread was exited!");
}




int main()
{
    pthread_t thread_id;
    void *thread_result;
    int c=0;
    int l=pthread_create(&thread_id,NULL,timerfunction,&c);
    int t1= counter;//reading the counter for the first one

    //intended instruction that we want to measure its execution time   

    int t2= counter;//reading the counter for the second one
    int t3 = t2 - t1;//computing the time
    printf ("value in the counter is: %d \n", t3);
    return 0;
}

我的理解是,Wasm 对多线程的支持并不完善,因为它不会同时运行主线程和其他线程,它需要像 sleep 这样的东西来在线程之间切换。因此,我们不能将多线程 Wasm 用于某些目标,例如在一个线程中增加一个计数器并在另一个线程中同时读取它。我的问题是我的推论是否正确?如果是真的,问题是什么?从 C 或编译过程或...?是否有任何替代方法可以使用完整的多线程?非常感谢。

标签: multithreadingemscriptenwebassemblywasm-bindgen

解决方案


你很幸运,Emscripten 已经实现了 PThreads with shared memory

有一些警告

截至 2019 年 9 月,由于 Spectre 漏洞,一些浏览器已禁用 SharedArrayBuffer。在它恢复之前,如果您在这些浏览器中翻转首选项,您仍然可以尝试它。在其他浏览器(如桌面版 Chrome)中,SharedArrayBuffer 默认完全启用,您无需翻转任何标志。

它是一种创建用于 Spectre/Meltdown 攻击的计时器的机制

请注意,在 2018 年 1 月 5 日,所有主要浏览器默认禁用 SharedArrayBuffer,以响应 Spectre。Chrome 在 v67 中在启用了站点隔离功能以防止 Spectre 式漏洞的平台上重新启用了它。

我没有测试过,但以下可能有效

# Assuming you have a makefile, the following might work
sudo docker run --rm -v $(pwd):/src trzeci/emscripten emmake make
sudo docker run --rm -v $(pwd):/src trzeci/emscripten emcc \
src/main.o \
-s ALLOW_MEMORY_GROWTH=1 \
-s ERROR_ON_UNDEFINED_SYMBOLS=0 \
-s USE_PTHREADS=1 \

推荐阅读