Skip to main content

Що таке SharedArrayBuffer?

Визначення

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

ВластивістьArrayBufferSharedArrayBuffer
Копіюється при передачіТакНі
Спільний доступ між потокамиНіТак
Підтримка 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, коли потрібно обмінюватися даними швидко, без копіювання й з контролем синхронізації.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.