SharedArrayBuffer支持多线程零拷贝共享内存,但需跨域隔离、Atomics同步及transfer list传递。
SharedArrayBuffer 允许多个 Web Worker(以及主线程)直接访问同一块内存,无需序列化/复制,是处理海量原始数据(如音频采样、图像像素、科学计算数组)时实现零拷贝共享的关键机制。但需注意:它不提供自动同步,必须配合 Atomics 手动协调读写,且现代浏览器默认要求跨域隔离(Cross-Origin Isolation)才能启用。
Chrome 92+、Firefox 93+ 等主流浏览器已默认禁用 SharedArrayBuffer,除非页面满足跨域隔离要求,否则会抛出 SharedArrayBuffer is not defined 或静默失败。
crossorigin 属性,例如:<script src="worker.js" type="module" crossorigin></script>
self.crossOriginIsolated 在 Worker 或主线程中检查是否就绪:if (crossOriginIsolated) { /* 可安全使用 SharedArrayBuffer */ }
通常由主线程创建缓冲区,再通过 postMessage 传给各 Worker。注意:传递的是引用,不是副本。
const sab = new SharedArrayBuffer(1024 * 1024 * 1024); // 1GBconst int32View = new Int32Array(sab);worker.postMessage({ buffer: sab }, [sab]); // 必须在 transfer list 中列出
self.onmessage = ({ data }) => { const { buffer } = data; if (buffer instanceof SharedArrayBuffer) { const view = new Float64Array(buffer); // 按需创建视图 }};
sab 放入 postMessage 的第二个参数(transfer list),否则会报错或仅传递普通 ArrayBuffer。SharedArrayBuffer 本身不保证操作原子性。多个 Worker 同时写同一位置会导致竞态;同时读写可能读到撕裂值。必须用 Atomics 显式同步。
Atomics.add(int32View, 0, 1); // 原子加法,返回旧值Atomics.load(int32View, 0); // 原子读取Atomics.store(int32View, 0, 42); // 原子写入
Atomics.wait(int32View, 0, 0); // 阻塞直到位置 0 不等于 0Atomics.notify(int32View, 0, 1); // 唤醒最多 1 个等待者
Atomics.wait() 替代 while (true) { ... },节省 CPU。直接裸用 SharedArrayBuffer + Atomics 较底层,实际项目中常封装为更高级的结构。
Atomics.compareExchange 协调边界。console.time() 对比 SAB 与普通 postMessage 传输大数组的耗时差异明显。