JavaScript通过SharedArrayBuffer实现共享内存,允许多个线程访问同一内存块,提升大数据处理性能。2. 创建SharedArrayBuffer实例并用postMessage传递引用,实现主线程与Worker间高效通信。3. 必须配合Atomics对象进行原子操作,防止数据竞争。4. 使用受限于跨域隔离策略,需服务器配置COOP和COEP头部以确保安全。5. 相比postMessage的序列化复制,SharedArrayBuffer避免了数据传输开销,适合高性能场景。

在JavaScript中实现共享内存,核心就是利用
SharedArrayBuffer
要使用
SharedArrayBuffer
ArrayBuffer
SharedArrayBuffer
创建一个
SharedArrayBuffer
const sharedBuffer = new SharedArrayBuffer(1024); // 创建一个1KB的共享内存 const sharedInt32Array = new Int32Array(sharedBuffer); // 创建一个视图,以便操作其中的整数数据
创建后,你可以通过
postMessage
sharedBuffer
SharedArrayBuffer
在主线程:
const worker = new Worker('worker.js');
const sharedBuffer = new SharedArrayBuffer(1024);
const sharedArray = new Int32Array(sharedBuffer);
// 初始化一些数据
for (let i = 0; i < sharedArray.length; i++) {
sharedArray[i] = i;
}
worker.postMessage({ buffer: sharedBuffer });
worker.onmessage = (event) => {
console.log('Worker更新后的数据:', sharedArray[0]); // 看看worker是不是真的改了
};在
worker.js
onmessage = (event) => {
const sharedBuffer = event.data.buffer;
const sharedArray = new Int32Array(sharedBuffer);
// Worker修改共享内存中的数据
sharedArray[0] = 999;
console.log('Worker内部修改数据:', sharedArray[0]);
// 通知主线程,或者继续操作
postMessage('数据已更新');
};需要特别注意的是,为了防止数据竞争(race condition)和确保操作的原子性,当多个线程同时读写共享内存时,必须配合
Atomics
Atomics
Atomics.add()
Atomics.load()
Atomics.store()
Atomics.wait()
Atomics.notify()
一个简单的原子操作示例:
// 在主线程或Worker中 Atomics.add(sharedArray, 0, 1); // 原子地将sharedArray[0]的值增加1 const value = Atomics.load(sharedArray, 0); // 原子地读取sharedArray[0]的值
另外,
SharedArrayBuffer
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
SharedArrayBuffer
ArrayBuffer
这其实是个关于安全和性能的权衡。
SharedArrayBuffer
SharedArrayBuffer
为了应对这些潜在的风险,浏览器厂商选择对
SharedArrayBuffer
SharedArrayBuffer
传统上,Web Worker和主线程之间的数据传递主要依赖
postMessage
postMessage
然而,当数据量变得非常庞大时,比如几十兆甚至上百兆的图像数据、视频帧或者大型数据集,序列化和反序列化的开销就会变得非常显著。这不仅会消耗大量的CPU资源,还可能导致主线程的卡顿,影响用户体验。
SharedArrayBuffer
数据竞争是并发编程中一个非常常见且棘手的问题,当多个线程同时访问和修改共享资源(这里就是
SharedArrayBuffer
为了解决这个问题,JavaScript提供了
Atomics
Atomics
以下是一些常用的
Atomics
Atomics.load(typedArray, index)
Atomics.store(typedArray, index, value)
Atomics.add(typedArray, index, value)
value
Atomics.sub(typedArray, index, value)
value
Atomics.compareExchange(typedArray, index, expectedValue, replacementValue)
typedArray[index]
expectedValue
replacementValue
Atomics.wait(typedArray, index, value, timeout)
typedArray[index]
value
Atomics.notify(typedArray, index, count)
typedArray[index]
举个简单的例子,假设我们有一个共享计数器:
// sharedBuffer 是 SharedArrayBuffer,counterArray 是 Int32Array 视图 const counterArray = new Int32Array(sharedBuffer); counterArray[0] = 0; // 初始化计数器 // 在多个Worker中,如果都直接 counterArray[0]++,就会有竞争问题 // 正确做法是使用 Atomics.add Atomics.add(counterArray, 0, 1); // 原子地增加计数器
通过
Atomics.add
更复杂的场景,比如一个Worker需要等待另一个Worker完成某项任务才能继续:
// Worker A
// ...执行一些耗时操作...
Atomics.store(statusArray, 0, 1); // 设置状态为“完成”
Atomics.notify(statusArray, 0, Infinity); // 唤醒所有等待的Worker
// Worker B
// ...做一些准备工作...
// 等待 Worker A 完成
const status = Atomics.wait(statusArray, 0, 0); // 如果 statusArray[0] 还是 0,就等待
if (status === 'ok') {
// Worker A 已经完成,可以继续了
} else if (status === 'timed-out') {
console.warn('等待超时!');
}通过
Atomics.wait
Atomics.notify
Atomics
SharedArrayBuffer
以上就是JS如何实现SharedArrayBuffer?共享内存的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号