Каталог
Веб-разработка с нуля: четыре курса по порядку.
HTML, затем CSS, JavaScript и SQL. Каждый курс говорит, что нужно знать до него и что вы будете уметь после.
Загружаем курсы…
Каталог
HTML, затем CSS, JavaScript и SQL. Каждый курс говорит, что нужно знать до него и что вы будете уметь после.
Загружаем курсы…
Урок 112 из 114 · 9 мин
SharedArrayBuffer, grow, growable, maxByteLength, byteLength, slice и Atomics: load, store, add, sub, and, or, xor, exchange, compareExchange, isLockFree, wait, waitAsync, notify, pause.
Два потока одновременно сделают count++ — и один заказ пропадёт! Хе-хе.
Для общей памяти есть атомарные операции: они выполняются целиком, никто не вклинится.
SharedArrayBuffer · byteLength · slice()if (typeof SharedArrayBuffer === "undefined") {
console.log("SharedArrayBuffer доступен только на страницах с изоляцией (COOP/COEP)");
} else {
const sab = new SharedArrayBuffer(8);
console.log(sab.byteLength, sab.slice(0, 4).byteLength);
}growable · maxByteLength · grow()new SharedArrayBuffer(4, { maxByteLength: 16 }); общий буфер может только расти: grow(n).if (typeof SharedArrayBuffer === "undefined") {
console.log("SharedArrayBuffer доступен только на страницах с изоляцией (COOP/COEP)");
} else {
const sab = new SharedArrayBuffer(4, { maxByteLength: 16 });
sab.grow(8);
console.log(sab.growable, sab.byteLength, sab.maxByteLength);
}Atomics · load() · store() · add()Atomics — объект с атомарными операциями над целочисленными типизированными массивами: load, store, add (возвращает старое значение). Работают и с обычными буферами.const counter = new Int32Array(new ArrayBuffer(4));
Atomics.store(counter, 0, 10);
console.log(Atomics.add(counter, 0, 5), Atomics.load(counter, 0));Atomics.sub() · and() · or() · xor()const a = new Int32Array(new ArrayBuffer(4));
Atomics.store(a, 0, 0b1100);
Atomics.or(a, 0, 0b0001);
Atomics.and(a, 0, 0b1101);
Atomics.xor(a, 0, 0b1000);
Atomics.sub(a, 0, 1);
console.log(a[0]);Atomics.exchange() · compareExchange() · isLockFree()exchange — записать и вернуть старое; compareExchange(arr, i, ожидаемое, новое) — записать, только если там ожидаемое (основа блокировок); isLockFree(n) — работают ли операции размера n без блокировок.const lock = new Int32Array(new ArrayBuffer(4));
console.log(Atomics.compareExchange(lock, 0, 0, 1), Atomics.compareExchange(lock, 0, 0, 1), Atomics.exchange(lock, 0, 0), Atomics.isLockFree(4));Atomics.wait() · waitAsync() · notify() · pause()wait — уснуть, пока значение не изменится (только в worker и с общим буфером), waitAsync — то же через промис, notify — разбудить ждущих, pause — подсказка процессору в цикле ожидания.const a = new Int32Array(new ArrayBuffer(4));
console.log(typeof Atomics.wait, typeof Atomics.waitAsync, Atomics.notify(a, 0, 1));
Atomics.pause?.();Общая память без Atomics — гонки и потерянные данные. Каждое общее изменение — атомарной операцией.
Напиши nextOrder(counter): атомарно увеличивает counter[0] на 1 и возвращает новый номер (через Atomics.add, который возвращает старое значение).
Atomics.add — пока нетВыберите один ответ.
Почему count++ из двух потоков может потерять увеличение?
Проверяем состояние обучения…