前言
JavaScript 一直以来都是运行在单线程里面的语言,因为这个特性导致了 JavaScript 的并发、多线程处理一直都是麻烦的事情,虽然深度学习、GPU 等高并发场景在前端并不普遍,但是随着 Node.js 的普及以及浏览器越来越强大,JavaScript 对多线程处理的需求越来越大。
之前程序员们会使用 Web Worker 实现多线程,但是 Web Worker 在并发控制和共享内存上存在一些问题。在 ECMAScript9 中提出的 Shared Array Buffers 提供了一种解决方案。
Shared Array Buffers
JavaScript 开发者们最为熟悉的可能就是 Array Buffer 了,Array Buffer 是一种类似数组的对象,它可以用来存储任意形式的二进制数据,之前大家主要使用它来在浏览器和 node.js 之间传递二进制数据。Shared Array Buffers 是一种新的 Array Buffer 类型,提供了一种机制,让多个 worker 线程之间共享底层的 ArrayBuffer。这意味着多个线程可以在没有锁的情况下读写相同的数据。
由于 Shared Array Buffers 技术关键是实现共享内存,即多个执行上下文可以访问同一个内存区域,因此它的使用必须非常小心谨慎,以避免竞态条件和其他内存安全问题。
示例代码
let buffer = new SharedArrayBuffer(16); // 16 byte 的 SharedArrayBuffer let int16Array = new Int16Array(buffer); int16Array[0] = 0; int16Array[1] = 1; let worker = new Worker("worker.js"); worker.postMessage(buffer); worker.onmessage = function(event) { console.log("The sum is", event.data); // 显示 sum :1 };
共享内存内存模型
Shared Array Buffers 是共享内存模型。共享内存模型是最基本的内存模型,它基于 CPU 的内存模型。共享内存模型有两种方式:原子操作和设备内存。
原子操作
Shared Array Buffers 使用原子操作来管理多个线程对同一对象的并发修改。原子操作不可分割,并且永远不会同时被多个线程执行(是线程安全的)。
在 Shared Array Buffers 中,Int8Array、Uint8Array、Int16Array、Uint16Array、Int32Array、Uint32Array、Float32Array 以及 Float64Array 都是原子对象。
设备内存
元素数据类型确定了示例内存块的字节大小,即 Shared Array Buffers 类型数组。 Shared Array Buffers 类型数组的偏移量可以是任意从 0 开始的整数。
几个注意点
由于 Shared Array Buffers 技术涉及到共享内存,因此在使用的过程中需要注意以下几个事项:
- SharedArrayBuffer 对象的大小必须在 1-4294967295 个字节之间。
- 确保并发访问的 ArrayBuffer 被同步访问,不然在 shared memory 中的内容不会被写回主内存,并且可能因为缓存而导致数据不一致。
- SharedArrayBuffer 不能被传递给老的 Web Worker(在新的规范中已经不能实例化),可以传递给 SharedWorker 或 Service Worker。
- SharedArrayBuffer 使用属于共享 Worker 的上下文,不能被非共享 worker 访问。
如果使用 SharedArrayBuffer
Shared Array Buffers 提供了一种新的多线程处理方案。虽然使用需要特别小心,但是可以大大提供程序的性能。在使用 Shared Array Buffers 引入微调之前,需要评估缺点。
总结
Shared Array Buffers 技术允许多个线程之间在共享内存空间上处理数据,这种技术极大地提高了性能。同样,共享内存也增加了开发的乐趣,让程序员可以更方便地理解代码,以及做有意义的事情。
代码示例:https://github.com/petehunt/worker-data。感谢 Pete Hunt 和 Mozilla 团队的工作。
希望这篇文章能够帮助读者学会如何使用 Shared Array Buffers 技术。如果读者在使用的过程中遇到了问题,可以随时在社区中与我们联系。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6594b1d6eb4cecbf2d8fca73