Атомарные операции
Базовый уровень Широко доступно
Эта функция хорошо зарекомендовала себя и работает на множестве устройств и версий браузеров. Она доступна в браузерах с декабря 2021 года.
Объект пространства имен Atomics содержит статические методы для выполнения атомарных операций. Они используются с объектами SharedArrayBuffer и ArrayBuffer.
Описание
В отличие от большинства глобальных объектов, Atomics не является конструктором. Вы не можете использовать его с оператором new или вызывать объект Atomics как функцию. Все свойства и методы Atomics являются статическими (как и объект Math).
Атомарные операции
При совместном использовании памяти несколько потоков могут читать и записывать одни и те же данные в памяти. Атомарные операции гарантируют, что предсказуемые значения записываются и считываются, что операции завершаются до начала следующей операции и что операции не прерываются.
Ожидание и уведомление
Методы wait() и notify() смоделированы по образцу futex ("быстрый мьютекс пользовательского пространства") в Linux и предоставляют способы ожидания наступления определенного условия. Обычно они используются как блокирующие конструкции.
Статические свойства
-
Atomics[Symbol.toStringTag] - Начальное значение свойства
[Symbol.toStringTag]— это строка"Atomics". Это свойство используется вObject.prototype.toString().
Статические методы
-
Atomics.add() - Добавляет предоставленное значение к существующему значению по указанному индексу массива. Возвращает старое значение по этому индексу.
-
Atomics.and() - Вычисляет побитовое И между значением по указанному индексу массива и предоставленным значением. Возвращает старое значение по этому индексу.
-
Atomics.compareExchange() - Сохраняет значение по указанному индексу массива, если оно равно другому значению. Возвращает старое значение.
-
Atomics.exchange() - Сохраняет значение по указанному индексу массива. Возвращает старое значение.
-
Atomics.isLockFree() - Оптимизирующий примитив, который можно использовать для определения того, следует ли использовать блокировки или атомарные операции. Возвращает
true, если атомарная операция над массивами указанного размера элементов будет реализована с использованием аппаратной атомарной операции (в отличие от блокировки). Только для экспертов. -
Atomics.load() - Возвращает значение по указанному индексу массива.
-
Atomics.notify() - Уведомляет агентов, ожидающих по указанному индексу массива. Возвращает количество уведомленных агентов.
-
Atomics.or() - Вычисляет побитовое ИЛИ между значением по указанному индексу массива и предоставленным значением. Возвращает старое значение по этому индексу.
-
Atomics.pause() - Предоставляет примитив микроожидания, который подсказывает ЦП, что вызывающий поток вращается в ожидании доступа к совместно используемому ресурсу. Это позволяет системе сократить ресурсы, выделенные ядру (например, питание) или потоку, не отказываясь от текущего потока.
-
Atomics.store() - Сохраняет значение по указанному индексу массива. Возвращает значение.
-
Atomics.sub() - Вычитает значение по указанному индексу массива. Возвращает старое значение по этому индексу.
-
Atomics.wait() - Проверяет, что указанный индекс массива все еще содержит значение, и спит в ожидании или истекает время ожидания. Возвращает
"ok","not-equal"или"timed-out". Если ожидание не разрешено в вызывающем агенте, выбрасывается исключение. (Большинство браузеров не разрешаютwait()в основной поток браузера.) -
Atomics.waitAsync() - Асинхронно ожидает (то есть без блокировки, в отличие от
Atomics.wait) в общем расположении памяти и возвращает объект, представляющий результат операции. -
Atomics.xor() - Вычисляет побитовое ИСКЛЮЧАЮЩЕЕ ИЛИ между значением по указанному индексу массива и предоставленным значением. Возвращает старое значение по этому индексу.
Примеры
Обратите внимание, что эти примеры нельзя запускать напрямую из консоли или произвольной веб-страницы, поскольку SharedArrayBuffer не определяется, если не выполнены его требования безопасности.
Использование атомарных операций
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 Atomics.and(ta, 0, 1); // 17 Atomics.load(ta, 0); // 1 Atomics.compareExchange(ta, 0, 5, 12); // 1 Atomics.load(ta, 0); // 1 Atomics.exchange(ta, 0, 12); // 1 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); // 12 Atomics.load(ta, 0); // 13 Atomics.store(ta, 0, 12); // 12 Atomics.sub(ta, 0, 2); // 12 Atomics.load(ta, 0); // 10 Atomics.xor(ta, 0, 1); // 10 Atomics.load(ta, 0); // 11
Ожидание и уведомление
Учитывая общий Int32Array:
const sab = new SharedArrayBuffer(1024); const int32 = new Int32Array(sab);
Поток чтения спит и ожидает по расположению 0, потому что предоставленное значение совпадает с тем, что хранится по указанному индексу. Поток чтения не продвинется дальше, пока поток записи не вызовет Atomics.notify() для позиции 0 предоставленного типизированного массива. Обратите внимание, что если после пробуждения значение расположения 0 не было изменено потоком записи, поток чтения не вернется ко сну, а продолжит работу.
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);
Спецификации
Совместимость с браузерами
| Настольные компьютеры | Мобильные | Сервер | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox для Android | Opera Android | Safari на iOS | Samsung Internet | WebView Android | WebView на iOS | Bun | Deno | Node.js | |
Atomics |
68 |
79 |
78 |
55 |
15.2До Safari 16.4Atomics был доступен через COOP/COEP. Подробнее читайте Сделайте свой веб-сайт «кросс-источниковым изолированным» с помощью COOP и COEP. |
89 |
79 |
63 |
15.2До Safari на iOS 16.4Atomics был доступен через COOP/COEP. Подробнее читайте Сделайте свой веб-сайт «кросс-источниковым изолированным» с помощью COOP и COEP. |
15.0 |
89 |
15.2До WebView на iOS 16.4Atomics был доступен через COOP/COEP. Подробнее читайте Сделайте свой веб-сайт «кросс-источниковым изолированным» с помощью COOP и COEP. |
1.0.0 |
1.0 |
8.10.0 |
Atomic_operations_on_non_shared_buffers |
Нет |
Нет |
79 |
Нет |
Нет |
Нет |
79 |
Нет |
Нет |
Нет |
Нет |
Нет |
1.0.0 |
Нет |
Нет |
add |
68 |
79 |
78 |
55 |
15.2 |
89 |
79 |
63 |
15.2 |
15.0 |
89 |
15.2 |
1.0.0 |
1.0 |
8.10.0 |
and |
68 |
79 |
78 |
55 |
15.2 |
89 |
79 |
63 |
15.2 |
15.0 |
89 |
15.2 |
1.0.0 |
1.0 |
8.10.0 |
compareExchange |
68 |
79 |
78 |
55 |
15.2 |
89 |
79 |
63 |
15.2 |
15.0 |
89 |
15.2 |
1.0.0 |
1.0 |
8.10.0 |
exchange |
68 |
79 |
78 |
55 |
15.2 |
89 |
79 |
63 |
15.2 |
15.0 |
89 |
15.2 |
1.0.0 |
1.0 |
8.10.0 |
isLockFree |
68 |
79 |
78 |
55 |
15.2 |
89 |
79 |
63 |
15.2 |
15.0 |
89 |
15.2 |
1.0.0 |
1.0 |
8.10.0 |
load |
68 |
79 |
78 |
55 |
15.2 |
89 |
79 |
63 |
15.2 |
15.0 |
89 |
15.2 |
1.0.0 |
1.0 |
8.10.0 |
notify |
68 |
79 |
78 |
55 |
15.2 |
89 |
79 |
63 |
15.2 |
15.0 |
89 |
15.2 |
1.0.0 |
1.0 |
8.10.0 |
or |
68 |
79 |
78 |
55 |
15.2 |
89 |
79 |
63 |
15.2 |
15.0 |
89 |
15.2 |
1.0.0 |
1.0 |
8.10.0 |
pause |
133 |
133 |
137 |
118 |
18.4 |
133 |
137 |
88 |
18.4 |
29.0 |
133 |
18.4 |
1.1.31 |
2.2 |
Нет |
store |
68 |
79 |
78 |
55 |
15.2 |
89 |
79 |
63 |
15.2 |
15.0 |
89 |
15.2 |
1.0.0 |
1.0 |
8.10.0 |
sub |
68 |
79 |
78 |
55 |
15.2 |
89 |
79 |
63 |
15.2 |
15.0 |
89 |
15.2 |
1.0.0 |
1.0 |
8.10.0 |
wait |
68 |
79 |
78 |
55 |
15.2 |
89 |
79 |
63 |
15.2 |
15.0 |
89 |
15.2 |
1.0.0 |
1.0 |
8.10.0 |
waitAsync |
90
|
90
|
145 |
75 |
16.4 |
90
|
145 |
64
|
16.4 |
15.0 |
90
|
16.4 |
1.0.0 |
1.4 |
16.0.0 |
xor |
68 |
79 |
78 |
55 |
15.2 |
89 |
79 |
63 |
15.2 |
15.0 |
89 |
15.2 |
1.0.0 |
1.0 |
8.10.0 |
См. также
ArrayBuffer- Руководство по типизированным массивам JavaScript
- Web Workers
- Общая память – краткое руководство в предложении TC39 ecmascript-sharedmem
- Вкус новых параллельных примитивов JavaScript на hacks.mozilla.org (2016)
© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics