Atomics - JavaScript 编辑
Atomics
对象提供了一组静态方法对 SharedArrayBuffer
和 ArrayBuffer
对象进行原子操作。
描述
这些原子操作属于 Atomics
模块。与一般的全局对象不同,Atomics
不是构造函数,因此不能使用 new 操作符调用,也不能将其当作函数直接调用。Atomics
的所有属性和方法都是静态的(与 Math
对象一样)。
原子操作
多个共享内存的线程能够同时读写同一位置上的数据。原子操作会确保正在读或写的数据的值是符合预期的,即下一个原子操作一定会在上一个原子操作结束后才会开始,其操作过程不会中断。
等待和通知
wait()
和 notify()
方法采用的是 Linux 上的 futexes 模型(“快速用户空间互斥量”),可以让进程一直等待直到某个特定的条件为真,主要用于实现阻塞。
方法
Atomics.add()
- 将指定位置上的数组元素与给定的值相加,并返回相加前该元素的值。
Atomics.and()
- 将指定位置上的数组元素与给定的值相与,并返回与操作前该元素的值。
Atomics.compareExchange()
- 如果数组中指定的元素与给定的值相等,则将其更新为新的值,并返回该元素原先的值。
Atomics.exchange()
- 将数组中指定的元素更新为给定的值,并返回该元素更新前的值。
Atomics.isLockFree(size)
- 可以用来检测当前系统是否支持硬件级的原子操作。对于指定大小的数组,如果当前系统支持硬件级的原子操作,则返回
true
;否则就意味着对于该数组,Atomics
对象中的各原子操作都只能用锁来实现。此函数面向的是技术专家。 Atomics.load()
- 返回数组中指定元素的值。
Atomics.notify()
- 唤醒等待队列中正在数组指定位置的元素上等待的线程。返回值为成功唤醒的线程数量。
Atomics.or()
- 将指定位置上的数组元素与给定的值相或,并返回或操作前该元素的值。
Atomics.store()
- 将数组中指定的元素设置为给定的值,并返回该值。
Atomics.sub()
- 将指定位置上的数组元素与给定的值相减,并返回相减前该元素的值。
Atomics.wait()
- 检测数组中某个指定位置上的值是否仍然是给定值,是则保持挂起直到被唤醒或超时。返回值为 "
ok
"、"not-equal
" 或 "time-out
"。调用时,如果当前线程不允许阻塞,则会抛出异常(大多数浏览器都不允许在主线程中调用wait()
)。 Atomics.xor()
- 将指定位置上的数组元素与给定的值相异或,并返回异或操作前该元素的值。
示例
使用 Atomics
const sab = new SharedArrayBuffer(1024);
const ta = new Uint8Array(sab);
ta[0];
// 0
ta[0] = 5;
// 5
Atomics.add(ta, 0, 12);
// 5
Atomics.load(ta, 0);
// 17 ✅
// 12 ❌
Atomics.and(ta, 0, 1);
// 17
Atomics.load(ta, 0);
// 1
Atomics.compareExchange(ta, 0, 5, 12);
Atomics.load(ta, 0); // 12
Atomics.exchange(ta, 0, 12);
Atomics.load(ta, 0); // 12
Atomics.isLockFree(1); // true
Atomics.isLockFree(2); // true
Atomics.isLockFree(3); // false
Atomics.isLockFree(4); // true
Atomics.or(ta, 0, 1);
Atomics.load(ta, 0); // 5
Atomics.store(ta, 0, 12); // 12
Atomics.sub(ta, 0, 2);
Atomics.load(ta, 0); // 3
Atomics.xor(ta, 0, 1);
Atomics.load(ta, 0); // 4
Waiting 和 notifiying
给定一个共享的 Int32Array
:
const sab = new SharedArrayBuffer(1024);
const int32 = new Int32Array(sab);
读取线程正在休眠并位置0上等待。只要该位置应为0,它就不会继续。但是,一旦写入线程存储了新值,写入线程将通知它并返回新值(123)。
Atomics.wait(int32, 0, 0);
console.log(int32[0]); // 123
写入线程存储一个新值并再写入完成时通知等待线程:
console.log(int32[0]); // 0;
Atomics.store(int32, 0, 123);
Atomics.notify(int32, 0, 1);
规范
Specification |
---|
ECMAScript (ECMA-262) Atomics |
浏览器兼容性
BCD tables only load in the browser
The compatibility table on this page is generated from structured data. If you'd like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.相关链接
ArrayBuffer
- JavaScript typed arrays
- Web Workers
- parlib-simple – a simple library providing synchronization and work distribution abstractions.
- Shared Memory – a brief tutorial
- A Taste of JavaScript’s New Parallel Primitives – Mozilla Hacks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论