JavaScript/SharedArrayBuffer

カテゴリ:Book:JavaScript#SharedArrayBuffer%20

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() 呼び出しによってコピーされるのではなく、参照として転送されます。

脚註

  1. これは、Web WorkerやServiceWorkerなどの並列実行環境間でメモリを共有するために使用されます。

外部リンク

カテゴリ:Book:JavaScript#SharedArrayBuffer%20 カテゴリ:JavaScript
カテゴリ:Book:JavaScript カテゴリ:JavaScript カテゴリ:Pages using the JsonConfig extension