JavaScript/SharedArrayBuffer
SharedArrayBuffer
オブジェクトは、固定長のバイナリデータバッファを表し、複数のエージェント(スレッドやワーカー)間で共有することができます。これにより、並列処理環境でのデータ共有が可能になります[1]。
構文
new SharedArrayBuffer(length)
length
: 作成するバッファのバイト単位の長さ。
プロパティ
SharedArrayBuffer.prototype
:SharedArrayBuffer
オブジェクトのプロトタイプを表します。SharedArrayBuffer.prototype.byteLength
: バッファのバイト単位のサイズを返します(読み取り専用)。SharedArrayBuffer.prototype.growable
: バッファがサイズ変更可能かどうかを示すブール値を返します(読み取り専用)。SharedArrayBuffer.prototype.maxByteLength
: バッファの最大バイト長を返します(読み取り専用)。
メソッド
SharedArrayBuffer.prototype.slice(start, end)
: 指定した範囲の新しいSharedArrayBuffer
を作成します。SharedArrayBuffer.prototype.grow(newLength)
: 成長可能なバッファのサイズを新しい長さに変更します。
例
基本的な使用方法
以下のプログラムは、SharedArrayBuffer
の基本的な使用方法を示しています。
// 1024バイトの共有バッファを作成 const buffer = new SharedArrayBuffer(1024); console.log(buffer.byteLength); // 1024 // Int32Arrayビューを作成 const int32View = new Int32Array(buffer); int32View[0] = 42; console.log(int32View[0]); // 42
このプログラムでは、1024バイトの SharedArrayBuffer
を作成し、そのバッファに対して Int32Array
ビューを作成しています。このビューを通じてバッファの内容を操作しています。
ワーカー間でのデータ共有
以下のプログラムは、メインスレッドとワーカー間で SharedArrayBuffer
を使用してデータを共有する例を示しています。
// メインスレッド const buffer = new SharedArrayBuffer(4); const view = new Int32Array(buffer); view[0] = 123; const worker = new Worker('worker.js'); worker.postMessage({ buffer }); worker.onmessage = function(event) { console.log(`ワーカーが値を ${view[0]} に更新しました`); }; // worker.js の内容 self.onmessage = function(event) { const { buffer } = event.data; const view = new Int32Array(buffer); console.log(`受け取った値: ${view[0]}`); // 値を更新 view[0] = 456; self.postMessage({ done: true }); };
このプログラムでは、メインスレッドが SharedArrayBuffer
を作成し、ワーカーに送信しています。ワーカーはバッファの内容を読み取り、更新します。この変更はメインスレッドからも見えます。
成長可能なSharedArrayBufferの使用
以下のプログラムは、サイズ変更可能な SharedArrayBuffer
を作成して使用する例を示しています。
// 初期サイズ8バイト、最大サイズ16バイトの成長可能なバッファを作成 const buffer = new SharedArrayBuffer(8, { maxByteLength: 16 }); console.log(buffer.byteLength); // 8 console.log(buffer.growable); // true console.log(buffer.maxByteLength); // 16 // バッファサイズを12バイトに拡張 buffer.grow(12); console.log(buffer.byteLength); // 12 // Int8Array ビューを作成 const view = new Int8Array(buffer); for (let i = 0; i < view.length; i++) { view[i] = i; } // バッファの内容を表示 console.log([...view]); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
このプログラムでは、初期サイズ8バイト、最大16バイトの成長可能な SharedArrayBuffer
を作成しています。grow()
メソッドを使用してバッファサイズを12バイトに拡張し、Int8Array
ビューを通じてバッファの内容を操作しています。
注意点
- セキュリティ制限: セキュリティ上の理由から、
SharedArrayBuffer
はクロスオリジン分離された環境でのみ利用可能です。これには、Cross-Origin-Opener-Policy: same-origin
およびCross-Origin-Embedder-Policy: require-corp
HTTPヘッダーが必要です。 - データ競合: 複数のスレッドが同時に同じデータにアクセスする場合、データ競合が発生する可能性があります。これを防ぐために、
Atomics
オブジェクトを使用して同期操作を行うことが推奨されます。 - 非同期通信:
SharedArrayBuffer
は、postMessage()
呼び出しによってコピーされるのではなく、参照として転送されます。
脚註
- ↑ これは、Web WorkerやServiceWorkerなどの並列実行環境間でメモリを共有するために使用されます。