WebAssembly多线程支持的内部原理

这篇博文探讨了 WebAssembly 支持多线程的内部机制与新的指令集,并介绍了这一功能如何为多线程应用程序提供支持。

几年前 WebAssembly 刚刚发布时还是一个 MVP(最小可行产品),只有很少的一组功能来提供基本的可用性和实用性。彼时这个 MVP 缺少一个重要特性,就是多线程支持。而如今 WebAssembly 的多线程支持已经非常成熟了,可在工具和 Chrome 中使用。这篇博文探讨了此功能的内部机制与新的指令集,并介绍了这一功能如何为多线程应用程序提供支持。

 

 

多线程和并发

在深入研究 WebAssembly 多线程规范的细节之前,我们先来简单了解一下并发和多线程技术,看看它们的涵义、我们使用这些技术的原因以及它们带来的挑战。如果你是这方面的老手,大可直接跳过这部分!

现代计算机有多个 CPU(而且每颗 CPU 有多个内核——但为了简单起见,我将它们都简称为 CPU),每个 CPU 都能够独立执行程序。我们可以通过多种方式利用这一优势。例如,如果你要处理一个计算密集型任务(如图像处理),则可以将任务拆分到多个 CPU 上以更快地完成工作;或者如果你的任务需要花费的时间不算短(比如说一两秒),那么最好不要把这个任务放到负责刷新应用 UI 的 CPU 上执行,而是把它放到另一个 CPU 上运行以保持 60fps 的 UI 帧速率。

线程是编程结构的底层,使你可以在这些 CPU 之间分配工作。线程和 CPU 之间没有直接映射关系,但实践中你需要创建多个线程来实现并发处理。

创建充分利用并发能力的应用程序是很有挑战性的,你必须推断每个执行的“线程”,每个线程都具有本地和共享状态的组合。你还需要其他一些工具,例如“(线程)锁”,用来防止多个线程执行同一段代码。但是这些工具又会引入进一步的挑战,例如过度锁定影响并发性或死锁等问题。

 

(一位程序员遇到了一个问题,他决定靠多线程解决这个问题!现在问题变成了两个。)

现代工具、框架和架构方法一般都会隐藏并发性,这很容易理解。NodeJS、Lambda 函数和主流浏览器都表现为单线程环境。个人来说,我必须承认自己上一次创建一个线程池是好几年以前的事情了!

虽然现在使用多线程的情况不太常见,但也有时候你还是要用它才行。

Web Worker和浏览器的并发性

有许多 API 支持 JavaScript 开发人员在浏览器中使用并发能力。我们简单看一下这些 API 和它们的现状。

Web 浏览器本质上是单线程的(从开发人员的角度来看),你的应用程序逻辑与 UI 呈现引擎共享相同的线程。因此长时间运行的计算将导致 UI 锁定或挂起。这种方法以较少的代价换来了极大的便利,所以众多 UI 框架(例如 WPF、WinForms、Cocoa/iOS)都采用了这种方法。

Web Worker API 可以让你生成“Worker”线程,这种 API 已经流行多年。你可以用它创建在给定文件中执行 JavaScript 的 Worker。尽管 Worker 可以发出 XHR 请求并使用 WebSockets,但它们没有 DOM 访问权限。Worker 不能与主(UI)线程共享可变数据,而是依赖于异步消息传递:

// ## main.js

const worker = new Worker("worker.js");
// pass a message to the worker
worker.postMessage("Hello World!");

// ## worker.js

// The onmessage property uses an event handler to retrieve information sent to a worker.
onmessage = event => {
console.log("Received message " + event.data);
};

Web Worker 提供了一个非常简单的 API,可以避免许多与并发相关的棘手问题。但实际上只有粗粒度的并发方法能这么简单地处理——所谓粗粒度是指传递给 worker 的都是相对较大的任务。

最近,新引入的 SharedArrayBuffer 和原子操作使开发人员能跨多个线程使用共享的内存了。这样以来就能实现更细粒度的并发算法。Lin Clark 写了一份精彩的卡通指南介绍了原子操作的重要性: https://hacks.mozilla.org/2017/06/a-crash-course-in-memory-management/

遗憾的是,虽然共享数组缓存之前已得到了广泛支持,但 Spectre 和 Meltdown 漏洞

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值