Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що таке SharedArrayBuffer?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`SharedArrayBuffer`** - тип об'єкта в JavaScript, що надає область пам'яті, доступну одночасно кільком потокам (наприклад, `worker_threads`), без копіювання даних під час передачі. **Ключове:** синхронізацію паралельного читання/запису забезпечує `Atomics` - без нього виникає стан гонки.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Визначення > `SharedArrayBuffer` - це спеціальний тип об'єкта в JavaScript, > який надає **спільну область пам'яті**, > доступну **одночасно кільком потокам** (наприклад, `worker_threads` у Node.js). ## Ідея Звичайні об'єкти й масиви під час передачі між потоками **копіюються**. `SharedArrayBuffer` дозволяє: - **розділяти** ту саму ділянку пам'яті між потоками, - **уникати копіювання** великих даних, - **синхронізувати доступ** через атомарні операції (`Atomics`). Простіше кажучи: > Це як "спільна RAM-ділянка", яку можуть читати й змінювати всі потоки всередині одного процесу Node.js. ## 1. Приклад використання **main.js** ```javascript const { Worker } = require('worker_threads'); // Створюємо спільний буфер на 4 байти * 10 елементів const shared = new SharedArrayBuffer(4 * 10); const sharedArray = new Int32Array(shared); sharedArray[0] = 10; sharedArray[1] = 20; const worker = new Worker('./worker.js', { workerData: shared }); worker.on('exit', () => { console.log('Головний потік бачить:', sharedArray[0], sharedArray[1]); // наприклад, 20 40 }); ``` **worker.js** ```javascript const { workerData } = require('worker_threads'); // workerData містить посилання на той самий SharedArrayBuffer const arr = new Int32Array(workerData); // Змінюємо значення в спільному буфері arr[0] *= 2; arr[1] *= 2; ``` Тут `main.js` і `worker.js` працюють з **однією й тією ж ділянкою пам'яті**. Зміни, зроблені в потоці, **негайно видно** в основному потоці. ## 2. Відмінність від `ArrayBuffer` | Властивість | `ArrayBuffer` | `SharedArrayBuffer` | |---|---|---| | Копіюється при передачі | Так | Ні | | Спільний доступ між потоками | Ні | Так | | Підтримка `Atomics` | Ні | Так | | Безпека при паралельному записі | Не застосовується | Лише з `Atomics` | | Типова мета | Буфер для одного потоку | Розділювана пам'ять між потоками | ## 3. Навіщо потрібен `Atomics` Коли кілька потоків одночасно читають/пишуть спільні дані, може виникнути **стан гонки (race condition)**. Щоб уникнути цього, використовується об'єкт `Atomics`, який виконує операції (читання, запис, інкремент тощо) **атомарно** - тобто гарантує, що операція завершиться повністю, перш ніж почнеться інша. Приклад: ```javascript const shared = new SharedArrayBuffer(4); const arr = new Int32Array(shared); Atomics.store(arr, 0, 5); Atomics.add(arr, 0, 2); console.log(Atomics.load(arr, 0)); // 7 ``` ## 4. Де застосовується `SharedArrayBuffer` **Корисний, коли:** - потрібно обмінюватися великими бінарними даними без копіювання; - виконуються **паралельні обчислення** (рендеринг, симуляції, ML, парсинг); - потрібна **висока швидкість** обміну між потоками (`worker_threads`); - потрібно реалізувати **розділюваний стан** із синхронізацією через `Atomics`. **Не потрібен, якщо:** - достатньо обміну повідомленнями (`postMessage`); - дані прості (рядки, JSON, об'єкти); - важливіша безпека, ніж продуктивність. ## 5. Переваги й недоліки | Перевага | Недолік | |---|---| | Швидка передача даних без копіювання | Небезпечний за неправильної синхронізації | | Економія пам'яті | Немає захисту від одночасного запису | | Можливість атомарних операцій | Складніше в налагодженні й розумінні | | Підтримується в браузерах і Node.js | Не можна передавати звичайні об'єкти | ## 6. Практичний приклад: лічильник між потоками **main.js** ```javascript const { Worker } = require('worker_threads'); const shared = new SharedArrayBuffer(4); const counter = new Int32Array(shared); counter[0] = 0; const worker1 = new Worker('./worker.js', { workerData: shared }); const worker2 = new Worker('./worker.js', { workerData: shared }); worker1.on('exit', () => worker2.on('exit', () => { console.log('Результат:', counter[0]); // 2000000 })); ``` **worker.js** ```javascript const { workerData } = require('worker_threads'); const counter = new Int32Array(workerData); for (let i = 0; i < 1_000_000; i++) { Atomics.add(counter, 0, 1); } ``` Обидва потоки безпечно збільшують **один і той самий лічильник** - без гонок даних, завдяки `Atomics`. ## Підсумок | Характеристика | Опис | |---|---| | Призначення | Розділювана пам'ять між потоками | | Тип | Об'єкт бінарної пам'яті | | Сумісний з | `TypedArray` (Int8Array, Float64Array тощо) | | Безпечна робота | Лише з `Atomics` | | Де використовується | У Node.js (`worker_threads`), браузерах (Web Workers) | | Переваги | Швидко, без копіювання, ефективно | | Недоліки | Складніша логіка, ризик гонок даних | **Висновок:** > `SharedArrayBuffer` - це "спільний шматок пам'яті", який кілька потоків можуть читати й змінювати одночасно. > У Node.js він використовується разом із `worker_threads` і `Atomics`, > коли потрібно обмінюватися даними **швидко, без копіювання й з контролем синхронізації**.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.