Main Content

parallel.pool.DataQueue

クライアントとワーカーの間でデータの送信とリスニングを可能にするクラス

説明

データ キューにより、計算の実行中に並列プール内のワーカーからクライアントにデータまたはメッセージを送り返すことができます。たとえば、計算の中間値と進行状況の指標を取得できます。

並列プールのワーカーからクライアントにデータを送り返すには、まずクライアント内に DataQueue を作成します。この DataQueue を、parfor ループ、または spmd などの他の並列言語構成に渡します。ワーカーから send を呼び出して、データをクライアントに送り返します。クライアントで、データを受信するたびに呼び出される関数を afterEach を使用して登録します。

  • 必要に応じて、コンストラクターを呼び出すプロセスから send を呼び出すことができます。

  • ワーカー上にキューを作成し、そのキューをクライアントに送り返すことにより、逆方向の通信を有効にできます。ただし、ワーカーから別のワーカーにキューを送信することはできません。代わりに spmdlabSend または labReceive を使用してください。

  • その他すべてのハンドル オブジェクトとは異なり、DataQueue インスタンスはワーカーに送信されても接続されたままとなります。

作成

説明

q = parallel.pool.DataQueue は引数を取らず、さまざまなワーカーからのメッセージ (またはデータ) の送信またはリスニングに使用できるオブジェクトを返します。データを受信するプロセス内でのみ、コンストラクターを呼び出します。通常のワークフローでは、ワーカーはコンストラクターを呼び出してはならず、代わりに既存の DataQueue インスタンスを渡されなければなりません。

プロパティ

すべて展開する

キューからの削除待ちのデータ アイテム数を示す読み取り専用プロパティ。値は 0 か、または DataQueue インスタンスを作成したプロセス上では正の整数です。その他すべてのプロセスで、値は 0 です。

オブジェクト関数

parallel.pool.DataQueue オブジェクトには以下のメソッドがあります。

afterEachDataQueue で新規データを受信したときに呼び出す関数の定義
sendデータ キューを使用したクライアントからワーカーへのデータの送信

すべて折りたたむ

メッセージを DataQueue オブジェクトに送信すると、メッセージはリスナーによって処理されるまでキューで待機します。メッセージごとに、キューの長さに 1 が加算されます。この例では、QueueLength プロパティを使用して DataQueue オブジェクトの長さを求めます。

MATLAB プロセスが DataQueue オブジェクトを作成すると、キューに送信されたすべてのメッセージはそのプロセスのメモリに保持されます。したがって、その他すべてのプロセスの QueueLength プロパティは 0 です。この例ではクライアント上に DataQueue オブジェクトを作成し、ワーカーからデータを送信します。

まず、1 つのワーカーをもつ並列プールを作成します。

parpool(1);
Starting parallel pool (parpool) using the 'local' profile ...
Connected to the parallel pool (number of workers: 1).

次に、DataQueue を作成します。

q = parallel.pool.DataQueue
q = 
  DataQueue with properties:

    QueueLength: 0

新規に作成された DataQueue には空のキューがあります。parfor を使用して、ワーカー上の q.QueueLength を求めることができます。クライアント上のキューの長さ、およびワーカー上のキューの長さを求めます。

fprintf('On the client: %i\n', q.QueueLength)
On the client: 0
parfor i = 1
    fprintf('On the worker: %i\n', q.QueueLength)
end
On the worker: 0

キューは空であるため、クライアントとワーカーの両方で QueueLength0 です。次に、ワーカーからキューにメッセージを送信します。続いて、QueueLength プロパティを使用してキューの長さを求めます。

% Send a message first
parfor i = 1
    send(q, 'A message');
end

% Find the length
fprintf('On the client: %i\n', q.QueueLength)
On the client: 1
parfor i = 1
    fprintf('On the worker: %i\n', q.QueueLength)
end
On the worker: 0

QueueLength プロパティはクライアントで 1 であり、ワーカーで 0 です。データをただちに表示してキューを処理するリスナーを作成します。

el = afterEach(q, @disp);

キューが空になるまで待ってから、リスナーを削除します。

while q.QueueLength > 0
    pause(0.1);
end
delete(el);

QueueLength プロパティを使用して、キューの長さを求めます。

fprintf('On the client: %i\n', q.QueueLength)
On the client: 0

キューの処理が完了しているため、QueueLength0 です。

DataQueue を作成し、afterEach を呼び出します。

q = parallel.pool.DataQueue;
afterEach(q, @disp);
parfor ループを開始し、メッセージを送信します。保留中のメッセージ (この例では @disp) が関数 afterEach に渡されます。

parfor i = 1:3
    send(q, i); 
end;
     1

     2

     3

DataQueue によるデータのリスニングの詳細については、afterEach を参照してください。

DataQueue を作成し、afterEach を使用して、キューがデータを受信するたびに実行される関数を指定します。この例では、ウェイト バーを更新するサブ関数を呼び出します。

計算負荷の高いタスクを MATLAB® で実行するために parfor ループを作成します。send を使用して、parfor ループの反復ごとにダミー データを送信します。キューがデータを受信すると、afterEach はクライアントの MATLAB で nUpdateWaitbar を呼び出し、ウェイト バーの進行状況が観察可能になります。

function a = parforWaitbar

D = parallel.pool.DataQueue;
h = waitbar(0, 'Please wait ...');
afterEach(D, @nUpdateWaitbar);

N = 200;
p = 1;

parfor i = 1:N
    a(i) = max(abs(eig(rand(400))));
    send(D, i);
end

    function nUpdateWaitbar(~)
        waitbar(p/N, h);
        p = p + 1;
    end
end

afterEach を呼び出したときに、キューにディスパッチ待ちのアイテムがある場合、これらのアイテムは afterEach で指定された関数ハンドルにただちにディスパッチされます。send で関数ハンドル @disp が必ず呼び出されるように、データをキューに送信する前に afterEach を呼び出します。

DataQueue を作成し、afterEach を呼び出します。

q = parallel.pool.DataQueue;
afterEach(q, @disp);
その後、キューにメッセージを送信すると、afterEach で指定された関数ハンドルに各メッセージがただちに渡されます。

parfor i = 1:3
    send(q, i); 
end
send(q, 0);
     1

     3

     2

     0

データをキューに送信してから afterEach を呼び出した場合、保留中の各メッセージが、afterEach で指定された関数ハンドルに渡されます。

q = parallel.pool.DataQueue;
parfor i = 1:3
    send(q, i); 
end
afterEach(q, @disp);
       3

       1

       2
R2017a で導入