SharedArrayBuffer 实现零拷贝并发需配合 TypedArray 映射同一内存、Atomics 保证原子操作、按核划分数据区间避免竞争;须启用跨域隔离策略,且存在浏览器兼容性限制。

SharedArrayBuffer 本身不提供零拷贝并发,它只是让多个线程(如主线程与 Worker)共享同一块原始内存;真正的零拷贝并发需配合 TypedArray、Atomics 和合理的内存布局设计来实现。关键在于避免数据复制、同步访问、并行计算分工明确。
用 SharedArrayBuffer + TypedArray 映射同一块内存
SharedArrayBuffer 是底层内存容器,必须通过 TypedArray(如 Int32Array、Float64Array)才能读写。多个 Worker 可各自用相同偏移创建视图,直接操作同一物理内存区域,无需序列化或复制数据。
- 主线程分配:
const sab = new SharedArrayBuffer(1024 * 1024); - 主线程与各 Worker 均创建视图:
const arr = new Int32Array(sab, 0, 256000); - 所有线程对
arr[i]的读写都作用于同一地址——这是零拷贝的基础
用 Atomics 保证安全的并发读写
普通赋值(arr[i] = x)在多线程下不是原子操作,可能导致竞态。必须用 Atomics 系列方法进行同步访问:
- 写入:用
Atomics.store(arr, i, value)替代arr[i] = value - 读取:用
Atomics.load(arr, i)替代arr[i] - 条件更新:用
Atomics.compareExchange(arr, i, oldVal, newVal)实现 CAS - 等待/通知:用
Atomics.wait()和Atomics.notify()协作任务调度
按核划分数据区间,实现无锁并行计算
零拷贝不等于无冲突。最高效的方式是让每个 Worker 处理互斥的内存段,完全规避同步开销:
- 假设有 4 个 Worker,数组长度为 1M 个 32 位整数,则每个 Worker 负责 250K 元素(起始索引分别为 0、250000、500000、750000)
- Worker 初始化时接收自己的
offset和length,仅操作new Int32Array(sab, offset * 4, length) - 全局结果可放在固定位置(如数组头部),由主线程或指定 Worker 汇总,用
Atomics.add()累加
注意浏览器限制与兼容性
SharedArrayBuffer 在现代浏览器中默认启用,但受跨域隔离策略约束:
- 页面必须启用
cross-origin-isolation(即响应头含Cross-Origin-Embedder-Policy: require-corp和Cross-Origin-Opener-Policy: same-origin) - 不支持 IE,Safari 16.4+ 才完整支持 Atomics.wait/notify
- Node.js 从 v20.0.0 起支持 SAB,但 Worker 线程模型与浏览器略有差异











