必须配置COOP和COEP响应头才能启用SharedArrayBuffer,Chrome 91+、Firefox 94+默认禁用该API;需同时设置Cross-Origin-Embedder-Policy: require-corp和Cross-Origin-Opener-Policy: same-origin,且仅HTTPS环境有效。

SharedArrayBuffer 必须配合跨域隔离策略才能启用
Chrome 91+、Firefox 94+ 默认禁用 SharedArrayBuffer,除非页面明确声明跨域隔离。不配就报错:SharedArrayBuffer is not defined 或 Failed to construct 'SharedArrayBuffer': SharedArrayBuffer is not enabled。
必须在服务器响应头中同时设置两项:
Cross-Origin-Embedder-Policy: require-corpCross-Origin-Opener-Policy: same-origin
本地开发时无法绕过——file:// 协议、未启用 HTTPS 的 localhost(如 http://localhost:8080)均无效。推荐用 npx serve --cors --headers '{"Cross-Origin-Embedder-Policy":"require-corp","Cross-Origin-Opener-Policy":"same-origin"}' 启服务。
主线程分配 + postMessage 传递 buffer 引用,不是数据
常见错误是把大数组直接 postMessage(array),结果触发结构化克隆,10MB 数据拷贝耗时 >10ms。正确路径是:主线程分配 SharedArrayBuffer,构造视图(如 Uint8Array),填入原始数据,再通过 postMessage(buffer, [buffer]) 把内存所有权移交 Worker。
立即学习“前端免费学习笔记(深入)”;
Worker 收到后直接复用同一块内存:
self.onmessage = (e) => {
const buf = e.data;
const view = new Uint8Array(buf); // 直接映射,零拷贝
console.log(view[0]); // 读取主线程写入的值
};注意:[buffer] 是 transfer list,传完主线程不能再访问该 buffer;若需双向读写,必须用 Atomics 同步。
多 Worker 并行处理 HTML 字符串时必须用 Atomics 同步
比如把一段 500KB 的 HTML 拆成 4 段,分发给 4 个 Worker 解析标签结构。若不加同步,多个 Worker 可能同时往共享内存同一偏移写入解析结果,导致数据错乱。
安全做法:
- 主线程预分配足够大的
SharedArrayBuffer,并用Int32Array视图管理状态位 - 每个 Worker 开始前调用
Atomics.compareExchange(stateView, index, 0, 1)尝试抢占任务槽 - 写结果前用
Atomics.store(resultView, offset, value),完成后Atomics.add(doneCounter, 0, 1) - 主线程用
Atomics.wait(doneCounter, 0, 4)等待全部完成
漏掉任何一次 Atomics 调用,都可能在高并发下出现竞态——这不是概率问题,是必然发生。
Rust 编译 WebAssembly 时必须启用 shared-memory 和 pthreads
想让 Wasm 模块内部也支持多线程(比如一个 Wasm 函数启动 4 个线程做矩阵分块计算),光靠 JS 层 Worker 不够。Rust 编译命令必须含:
cargo build --release --target wasm32-unknown-unknown \ -Z build-std=panic_abort,std \ --features=wee_alloc \ -C opt-level=3 \ -C target-feature=+bulk-memory,+simd128 \ -C lto=fat \ -C codegen-units=1
关键参数:-C target-feature=+bulk-memory,+simd128 启用内存操作和 SIMD;但真正开启线程能力,还需在 Cargo.toml 中添加:
[dependencies]
wasm-bindgen = "0.2"
js-sys = { version = "0.3", features = ["console"] }
# 必须启用 threads 特性
wasm-bindgen-futures = { version = "0.4", features = ["threads"] }否则生成的 .wasm 文件没有 memory 导出为 shared 类型,JS 层调用 WebAssembly.Memory 时会失败。
Wasm 线程模型和 JS Worker 是两套体系,混用时容易忽略内存所有权归属——Wasm 线程读写的内存,必须和 JS 层传递的 SharedArrayBuffer 是同一块物理内存,否则数据对不上。



















