浏览器 JavaScript 传统上单线程运行,难以处理 CPU 密集型任务如图像处理、机器学习推理或大数据计算。随着 Web 应用的复杂化,并行计算需求迫切。w4g1/multithreading 库巧妙利用 Web Workers 和 SharedArrayBuffer,构建线程池与共享内存机制,提供 Rust 风格的并发原语,包括 Mutex、RwLock、Semaphore、Condvar 和 MPMC Channels,实现高效浏览器端并行计算。
该库的核心是自动管理的 Worker 池,默认大小为 navigator.hardwareConcurrency,抽象了 Worker 创建、通信和终止的复杂性。通过 spawn 函数提交任务,支持 move 语义零拷贝传输 ArrayBuffer,避免序列化开销。共享内存基于 SharedArrayBuffer + Atomics.wait/notify,确保原子操作无竞态。不同于原生 Workers 的 postMessage 拷贝,该库的 SharedJsonBuffer 支持 JSON 对象部分更新,仅重序列化变更字节,提升性能。
例如,实现共享计数器:创建 SharedArrayBuffer (4),包装为 Mutex,多 Worker 通过 using guard = await mutex.acquire () 安全递增。证据显示,在 4 核浏览器中,并发 4 个 CPU 任务,吞吐提升 3.5 倍(基准测试于 repo 示例)。Channels 则用于管道:channel<{data: number}>() 创建 MPMC 队列,支持克隆 Sender/Receiver,多生产者多消费者场景如任务分发。
浏览器部署需跨源隔离:服务器设置 Cross-Origin-Opener-Policy: same-origin 和 Cross-Origin-Embedder-Policy: require-corp,确保 SharedArrayBuffer 可用。否则抛 AttribsNotShared 错误。库自动处理 import 路径补丁,支持相对模块和 npm 包动态加载,如 spawn 内 await import ('./utils.js')。
工程化参数建议:
- Worker 池大小:min (navigator.hardwareConcurrency, 8),避免过度上下文切换。
- SharedArrayBuffer 大小:任务需求 x 线程数 + 16KB 元数据,预分配 Uint32Array (1024) 用于锁。
- Mutex 超时:acquire () 默认无超时,生产加 {timeout: 5000ms} 参数防死锁。
- Channel 容量:任务批次大小,如 1024,结合 Semaphore (4) 限流。
- 移动数据阈值:>1MB 用 move (ArrayBuffer),小对象 structured clone。
落地清单:
- npm i multithreading;浏览器需 bundler 如 Vite 配置 worker: 'inline'。
- 服务器头:COOP: same-origin, COEP: require-corp;验证 self.crossOriginIsolated。
- 初始化:initRuntime ({poolSize: 6, idleTimeout: 30000ms}),空闲 Worker 30s 回收。
- 监控:handle.join () 捕获 Result<value, error>;Atomics 指标如 notify 计数。
- 回滚:fallback 单线程 spawn (fn),检测!self.crossOriginIsolated。
- 测试:基准 1000 迭代矩阵乘法,比较单 / 多线程 FPS。
风险控制:同步 API 如 acquireSync () 仅测试用,避免阻塞 Worker;大 Buffer 泄漏用 WeakRef 追踪。Channels 关闭检测:all Senders drop 后 recv 返回 None。
实际场景:WebGL 渲染农场,用 RwLock 共享场景数据,多 Worker 并行光追片段,读多写少优化。或 ML 推理:TensorFlow.js 模型分片至 Workers,Channel 聚合结果。
该库填补 JS 无内置 Atomics 高层封装空白,参数化设计便于调优。未来可扩展 GPU Compute via WebGPU。
资料来源:
- w4g1/multithreading GitHub Repo
- MDN SharedArrayBuffer(隐含知识)。
(正文字数约 1250)