必须开启crossOriginIsolated,否则SharedArrayBuffer未定义;需同时设置COEP和COOP响应头;线程安全依赖Atomics.wait/notify及原子指针操作;TypedArray视图须对齐且动态切片;Worker间传递必须用transfer list。

必须开启 crossOriginIsolated,否则 SharedArrayBuffer 会直接抛出 TypeError: SharedArrayBuffer is not defined —— 这是所有后续操作的前提,不是可选项。
为什么不能直接 new SharedArrayBuffer() 就开干
现代浏览器强制要求跨域隔离上下文才能启用共享内存。即使你在本地 file:// 协议下开发,也会失败;用 http://localhost 也不行,必须是 https:// 且响应头包含:
Cross-Origin-Embedder-Policy: require-corp Cross-Origin-Opener-Policy: same-origin
漏掉任一 header,SharedArrayBuffer 构造函数返回 undefined,所有基于它的环形缓冲区逻辑都会静默失效。常见错误是只配了 COPP(COOP),忘了 COEP(COEP)——两者缺一不可。
ringbuf.js 的线程安全模型依赖 Atomics.wait/notify
单消费者单生产者(SCSP)模型本身不自动线程安全,真正保证无竞争的关键是 Atomics.wait() 和 Atomics.notify() 配合缓冲区头尾指针的原子读写。例如:
-
push()写入前先Atomics.load(tail),写完后Atomics.store(tail, newTail),再Atomics.notify(head, 1) -
shift()读取前先Atomics.wait(head, expected),确保生产者已就绪 - 若跳过
Atomics直接用普通Int32Array操作指针,多线程下大概率读到撕裂值(torn read),缓冲区状态错乱
注意:Atomics.wait() 在 Chrome 91+ 有 V8 版本边界问题:某些中间版本中 notify 可能丢失,建议锁定使用 Chrome ≥93 或检查 Atomics.isLockFree(4) 返回 true 再启用。
TypedArray 视图必须与 SharedArrayBuffer 对齐且长度可控
环形缓冲区底层是 SharedArrayBuffer,但你操作的是其上的 Int16Array、Float32Array 等视图。关键约束:
- 缓冲区总字节长度必须是所选
TypedArray元素字节长的整数倍(如Float32Array单元素占 4 字节,则 buffer.byteLength % 4 === 0) - 避免用
new Float32Array(sharedBuf)创建全量视图——它会占用整个 buffer,无法做环形偏移;应始终用new Float32Array(sharedBuf, byteOffset, length)动态切片 - 实际可用容量不是
buffer.byteLength,而是(buffer.byteLength - headerSize) / elementByteLength,header 通常预留 8 字节存 head/tail 原子变量
错估长度会导致 RangeError: Invalid typed array length 或越界静默截断,尤其在音频帧(固定 20ms @ 48kHz = 960 个 Int16)场景下极易踩坑。
Worker 间传递时禁止序列化 SharedArrayBuffer
postMessage(sharedBuf, [sharedBuf]) 是唯一合法方式——必须显式传入 transfer list。如果写成 postMessage({ buf: sharedBuf }),主线程收到的是一个普通 ArrayBuffer 副本,不再是共享内存,零拷贝失效。
更隐蔽的坑:某些封装库(如旧版 audioqueue.js)内部做了浅拷贝或包装,需确认其 push() 方法是否最终调用了带 transfer list 的 postMessage。实测发现未 transfer 的“共享”缓冲区,性能反而比纯 postMessage 更差,因为多了序列化开销却没换来共享优势。
环形缓冲区的真正复杂点不在实现逻辑,而在于运行时上下文的完整性校验:crossOriginIsolated 状态、Atomics 支持度、TypedArray 对齐、transfer list 正确性——四者任意一个断裂,都会导致行为退化为不可预测的伪共享,而非预期的零拷贝高性能通路。











