
WebAssembly 支持通过显式声明 shared 属性创建可跨线程共享的内存,从而在主线程与 Web Worker 间安全高效地共享数据;本文详解如何定义、编译和使用共享内存,并强调关键限制与最佳实践。
webassembly 支持通过显式声明 `shared` 属性创建可跨线程共享的内存,从而在主线程与 web worker 间安全高效地共享数据;本文详解如何定义、编译和使用共享内存,并强调关键限制与最佳实践。
在默认情况下,WebAssembly 的 memory 导出为普通 ArrayBuffer,其底层 buffer 是不可共享的,无法直接用于 SharedArrayBuffer 所需的并发访问场景(如多线程协作或 Worker 通信)。若需实现线程安全的内存共享,必须在 Wasm 模块定义阶段明确声明内存为 shared。
✅ 正确声明共享内存
WAT(WebAssembly Text Format)中需在 memory 定义中添加 shared 关键字,并指定最小与最大页数(单位:64 KiB):
(module (memory (export "memory") 1 1 shared) ; 最小1页,最大1页,且标记为 shared (data (i32.const 0) "Hello World!") )
⚠️ 注意:shared 内存必须同时指定最小页数(required)和最大页数(required),且二者通常相等(不可动态增长),因为当前浏览器不支持 SharedArrayBuffer 的 grow() 操作。
? 编译与加载注意事项
-
使用 wabt 工具链(如 wat2wasm)编译时,确保输入 .wat 文件包含 shared 声明:
wat2wasm hello.wat -o hello.wasm
-
加载后验证内存类型:
fetch('hello.wasm') .then(res => res.arrayBuffer()) .then(bytes => WebAssembly.instantiate(bytes)) .then(result => { const memory = result.instance.exports.memory; console.log(memory.buffer instanceof SharedArrayBuffer); // true ✅ // 安全地创建共享视图(仅限主线程/Worker 同构环境) const sharedView = new Int32Array(memory.buffer); // 可配合 Atomics 进行同步操作 Atomics.store(sharedView, 0, 42); });
? 关键限制与最佳实践
- 浏览器兼容性:共享内存需启用 crossOriginIsolated 上下文(即页面需同时设置 Cross-Origin-Embedder-Policy: require-corp 和 Cross-Origin-Opener-Policy: same-origin),否则 SharedArrayBuffer 将被禁用。
- 不可增长性:shared 内存不支持 memory.grow(),因此务必在编译前预估足够容量。
- 线程安全:读写共享内存时,必须使用 Atomics API(如 Atomics.load, Atomics.wait, Atomics.notify)避免竞态条件。
- 初始化数据限制:data 段内容会复制到共享内存中,但仅在模块实例化时生效;运行时需通过 Atomics 或共享视图手动同步状态。
综上,WebAssembly 共享内存并非“开箱即用”,而是需要从模块定义、编译配置、运行时环境到并发控制全流程协同设计。正确声明 shared 并遵循隔离策略,才能真正释放 WebAssembly 在高并发场景下的性能潜力。











