百科狗-知识改变命运!
--

SharedArrayBuffer - JavaScript SharedArrayBuffer 对象

梵高1年前 (2023-11-21)阅读数 23#技术干货
文章标签对象

SharedArrayBuffer

SharedArrayBuffer对象用来表示一个通用的、固定长度的原始二进制数据缓冲区,类似于ArrayBuffer对象,它们都可以用来在共享内存(shared memory)上创建视图。与ArrayBuffer不同的是,SharedArrayBuffer不能被转移。

描述

分配及共享内存

SharedArrayBuffer - JavaScript SharedArrayBuffer 对象

为了将一个SharedArrayBuffer对象从一个用户代理共享到另一个用户代理(另一个页面的主进程或者当前页面的一个worker)从而实现共享内存,我们需要运用postMessage和结构化克隆算法。

结构化克隆算法接收SharedArrayBuffers对象,或被映射到一个新的SharedArrayBuffers对象上的TypedArrays对象。在这两种情况下,这个新的SharedArrayBuffer对象会被传递到目标用户代理的接收函数上,从而在目标用户代理产生一个新的私有SharedArrayBuffer对象(正如ArrayBuffer一样)。但是,这两个SharedArrayBuffer对象指向的共享数据块其实是同一个,所以某一代理对数据块的修改在另一个代理中可见。

var sab = new SharedArrayBuffer(1024);
worker.postMessage(sab);


通过原子操作更新及同步共享内存

共享内存能被同时创建和更新于worker线程或主线程。依赖于系统(CPU、操作系统、浏览器),变化传递给所有上下文环境需要一段时间。因此需要通过原子操作来进行同步。

接受 SharedArrayBuffer 对象的 API

  • WebGLRenderingContext.bufferData()
  • WebGLRenderingContext.bufferSubData()(en-US)
  • WebGL2RenderingContext.getBufferSubData()(en-US)


安全需求

为应对幽灵漏洞,所有主流浏览器均默认于 2018 年 1 月 5 日禁用 SharedArrayBuffer。在 2020 年,一种新的、安全的方法已经标准化,以重新启用SharedArrayBuffer。通过一些安全措施,postMessage()将不再抛出有关SharedArrayBuffer对象的异常,跨线程共享内存也变得可用:

作为基准需求,你的文档需处于安全上下文中。

对于顶级文档,需要设置两个 HTTP 消息头以跨域隔离你的站点:

  • Cross-Origin-Opener-Policy(en-US)设置为same-origin(保护源站免受攻击)
  • Cross-Origin-Embedder-Policy设置为require-corp(保护源站免受侵害)
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

为检查跨域隔离是否生效,你可以检查crossOriginIsolated属性在窗口和worker上下文中是否可用:

if (crossOriginIsolated) {
  // Post SharedArrayBuffer
} else {
  // Do something else
}

参阅 Planned changes to shared memory (en-US),以了解共享内存在浏览器中的变更计划(例如,Firefox 79)。


始终使用 new 运算符来构造 SharedArrayBuffer

SharedArrayBuffer必须使用new运算符来构造。作为函数来调用SharedArrayBuffer()构造函数(如果不用new运算符),将会抛出TypeError异常。

var sab = SharedArrayBuffer(1024);
// TypeError: calling a builtin SharedArrayBuffer constructor
// without new is forbidden
var sab = new SharedArrayBuffer(1024);


构造函数

SharedArrayBuffer()

创建一个SharedArrayBuffer对象。


实例属性

SharedArrayBuffer.prototype.byteLength

数组的大小(以字节为单位)。这是在构造数组时建立的,不能更改(只读)。


实例方法

SharedArrayBuffer.prototype.slice(begin, end)

返回一个新的SharedArrayBuffer,其为源数组从begin字节到end字节(不含end字节)的拷贝。若beginend为负数,则表示从数组末尾开始的索引。


示例

创建一个新的 SharedArrayBuffer

var sab = new SharedArrayBuffer(1024);


截取 SharedArrayBuffer

sab.slice();    // SharedArrayBuffer { byteLength: 1024 }
sab.slice(2);   // SharedArrayBuffer { byteLength: 1022 }
sab.slice(-2);  // SharedArrayBuffer { byteLength: 2 }
sab.slice(0, 1); // SharedArrayBuffer { byteLength: 1 }


在 WebGL buffer 中使用

const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, sab, gl.STATIC_DRAW);

鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)