在Chrome 70中体验WebAssembly线程

WebAssembly(Wasm)支持编译用C++和其他语言编写的代码,以便在Web上运行。 本机应用程序的一个非常有用的功能是使用线程的能力 - 用于并行计算的原语。大多数C和C++开发人员都熟悉pthreads,它是应用程序中线程管理的标准化API。

WebAssembly社区组一直致力于将线程引入Web以实现真正的多线程应用程序。 作为这项工作的一部分,V8已经为WebAssembly引擎中的线程实现了必要的支持,可通过Origin Trial获得。 Origin Trials允许开发人员在完全标准化之前尝试新的Web功能。 这使我们能够收集来自勇敢的开发人员的实际反馈,这对于验证和改进新功能至关重要.

Chrome 70支持WebAssembly线程,我们鼓励感兴趣的开发人员开始使用它们并向我们提供反馈。

线程? Workers怎么样?

从 2012 年的 Chrome 4 开始,浏览器们就利用 web workers 支持了并行;事实上听到类似于“在主线程上”的词语是很正常的。但是,Web Workers不会在它们之间共享可变数据,而是依赖于消息传递进行通信。 实际上,Chrome为每个引擎分配了一个新的V8引擎(称为隔离区)。 Isolates既不共享编译代码也不共享JavaScript对象,因此它们不能共享可变数据,如pthreads。

另一方面,WebAssembly线程是可以共享相同Wasm内存的线程。 共享内存的底层存储是通过SharedArrayBuffer完成的,SharedArrayBuffer是一个JavaScript原语,允许在worker之间共享单个ArrayBuffer的内容。 每个WebAssembly线程都在Web Worker中运行,但是它们共享的Wasm内存允许它们像在本机平台上一样工作。这意味着使用Wasm线程的应用程序负责管理对任何传统线程应用程序的共享内存的访问。有许多用C或C++编写的现有代码库使用pthreads,这些代码库可以编译为Wasm并以真正的线程模式运行,允许更多内核同时处理相同的数据。

一个简单的例子:

#include <pthread.h>
#include <stdio.h>

int fibonacci(int iterations)
{
  int val=1;
  int last=0;
  if(iterations==0)
  {
    return 0;
   }
  for(int i=1;i<iterations;i++)
  {
	  int seq;
	  seq=val+last;
	  last=val;
	  val=seq;

  }
  return val;
}
void *bg_func(void* arg)
{

	int *iter=(int*) arg;
	*iter=fibonacci(*iter);
	return arg;
}

int mian()
{
	int fg_val=54;
	int bg_val=42;
	pthread_t bg_thread;
	
	if(pthread_create(&bg_thread,NULL,bg_func,&bg_val))
	{

		perror("Thread create failed");
		return 1;
	}
	fg_val=fibonacci(fg_val);
	if(pthread_join(bg_thread,NULL))
	{
		perror("Thread join failed");
		return 2;
	}
	printf("Fib(42) is %d ,Fib(6*9) is %d\n",bg_val,fg_val);
	return 0;

}

该代码以main() 函数开头,该函数声明了2个变量fg_val和bg_val。 还有一个名为fibonacci() 的函数,在本例中将由两个线程调用。 main() 函数使用pthread_create()创建一个后台线程,其任务是计算与bg_val变量值对应的斐波纳契数序列值。同时,在前台线程中运行的main() 函数为fg_val变量计算它。 后台线程完成运行后,将打印出结果。

1.浏览器设置

测试我们的WebAssembly模块的最快方法是在Chrome 70以后启用实验性WebAssembly线程支持。 在浏览器中的访问chrome://flags,如下所示:

1.emcc编译

首先,您应该安装emscripten SDK,建议安装1.38.11或更高版本。要构建我们的示例代码,并且启用了在浏览器中运行的线程,我们需要将一些额外的标志传递给emscripten emcc编译器。

命令行参数'-s USE_PTHREADS = 1'打开编译的WebAssembly模块的线程支持,参数'-s PTHREAD_POOL_SIZE = 2'告诉编译器生成两(2)个线程池。

当程序运行时,它将加载WebAssembly模块,为线程池中的每个线程创建一个Web Worker,与每个worker共享模块,在这种情况下它是2,并且每次都会使用它们调用pthread_create()。 每个worker都使用相同的内存实例化Wasm模块,允许它们合作。 V8 7.0中的最新更改共享在工作程序之间传递的Wasm模块的编译本机代码,这使得即使是非常大的应用程序也可以扩展到许多工作程序。注意,确保线程池大小等于应用程序所需的最大线程数,或者线程创建可能失败是有意义的。同时,如果线程池大小太大,您将创建不必要的Web Workers,除了使用内存之外什么也不做。

我们的命令行如下所示:

emcc -O2 -s USE_PTHREADS=1 -s PTHREAD_POOL_SIZE=2 -o pthreadTest.html pthreadTest.cpp

2.开服务

http-server

3.运行

在浏览器中运行

若出现以上输出结果,则表示带有线程的WebAssembly程序已成功执行! 我们建议您使用上面列出的步骤尝试自己的线程应用程序。

英文原文

https://developers.google.com/web/updates/2018/10/wasm-threads

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值