WebAssembly能否导出共享内存?如何让导出内存支持Worker共享?
让WebAssembly内存支持共享的方法
要让WebAssembly导出的内存变为SharedArrayBuffer以支持Worker间共享,需要从Wasm模块定义和JS实例化配置两方面修改:
1. 修改Wasm模块的内存声明
在Wasm的memory定义中添加shared关键字,标记该内存支持共享特性:
(module (memory (export "memory") 1 shared) ; 新增shared关键字 (data (i32.const 0) "Hello World!") )
2. 在JS中配置共享实例化逻辑
有两种方式实现共享内存的实例化,根据需求选择即可:
方式一:实例化时直接指定共享选项
fetch('hello.wasm') .then(response => response.arrayBuffer()) .then(bytes => { return WebAssembly.instantiate(bytes, {}, { shared: true }); }) .then(result => { const memory = result.instance.exports.memory; const buffer = new Uint8Array(memory.buffer); const offset = 0; const length = 13; const message = new TextDecoder().decode(buffer.slice(offset, offset + length)); console.log(message); // 此时会输出"WebAssembly memory is shared." if (memory.buffer instanceof SharedArrayBuffer) { console.log("WebAssembly memory is shared."); } else { console.log("WebAssembly memory is not shared."); } }) .catch(error => console.error(error));
方式二:提前创建共享内存并导入
如果需要更灵活控制内存初始大小或增长上限,可以先创建基于SharedArrayBuffer的内存实例,再导入到Wasm模块中:
// 提前创建共享内存实例 const sharedMemory = new WebAssembly.Memory({ initial: 1, shared: true // 开启共享模式 }); fetch('hello.wasm') .then(response => response.arrayBuffer()) .then(bytes => { // 将自定义共享内存导入到Wasm模块 const importObj = { env: { memory: sharedMemory } }; return WebAssembly.instantiate(bytes, importObj); }) .then(result => { const memory = result.instance.exports.memory; console.log(memory.buffer instanceof SharedArrayBuffer); // 输出true // 后续内存操作逻辑同前 }) .catch(error => console.error(error));
关键注意事项
- 浏览器需支持WebAssembly Shared Memory特性(现代主流浏览器均已支持)。
- 使用
SharedArrayBuffer时,页面必须满足跨源隔离条件:需在服务器配置以下响应头,否则浏览器会自动降级为普通ArrayBuffer:Cross-Origin-Opener-Policy: same-origin Cross-Origin-Embedder-Policy: require-corp
内容的提问来源于stack exchange,提问作者a.gulcan
相关产品推荐
相关产品推荐

