フローグラフのノードとエッジを制御するクラス。
class graph;
#include "tbb/flow_graph.h"
graph オブジェクトには、フローグラフに基づいて作成されたすべてのタスクとそのノードの親となるルートタスクが含まれます。ルートタスクにアクセスするメソッド、ルートタスクの子が完了するのを待つメソッド、ルートタスクの参照カウントを明示的にインクリメントまたはデクリメントするメソッド、ルートタスクの子としてタスクを実行するメソッドが提供されます。
関連する graph オブジェクトの wait_for_all を呼び出す前にフローグラフのノードを破棄すると、不定の動作が発生し、プログラムの実行に失敗します。
フローグラフはキューに入れられたタスクの代わりにスポーンされたタスクを使用するようになりました。限定されたケースでは、ワーカースレッドが利用できない場合、wait_for_all に対する呼び出しが行われるまでグラフ関連のタスクは処理されません。wait_for_all に対する明示的な呼び出しを行わないようにするには、付録の「互換性機能」に記述されているように、タスクをキューに入れるフローグラフの実装を使用します。ただし、タスクをキューに入れるフローグラフの実装は非推奨です。必要な場合を除いて使用しないでください。
graph の実行中にキャンセルされるか例外がスローされると、wait_for_all() 後の状態と一貫性がなくなります。graph を再度実行する場合は、reset() メソッドを呼び出してグラフのエッジを初期状態にリセットする必要があります。
namespace tbb { namespace flow { // reset() メソッドのオプションフラグ enum reset_flags { rf_reset_protocol, rf_reset_bodies, // 現在のノードボディーを削除し、初期のノードボディーのコピーにリセット rf_clear_edges // ユーザーがグラフを再作成できるようにエッジをすべて削除 }; class graph { public: graph(); graph(task_group_context& context); ~graph(); void increment_wait_count(); void decrement_wait_count(); template< typename Receiver, typename Body > void run( Receiver &r, Body body ); template< typename Body > void run( Body body ); void wait_for_all(); task *root_task(); bool is_cancelled(); bool exception_thrown(); void reset(reset_flags f = rf_reset_protocol); }; } }
メンバー | 説明 |
---|---|
graph([task_group_context& group] ) |
ノードなしでグラフを構築します。group が指定されている場合、グラフのタスクはこのグループで実行されます。デフォルトでは、グラフはグラフがバインドされているコンテキストで実行されます。グラフの実行中に生成されるすべてのタスクの親として使用される、empty_task クラスのルートタスクを具体化します。ルートタスクの ref_count を 1 に設定します。 |
~graph() |
グラフの wait_for_all を呼び出して、ルートタスクを破棄します。 |
void increment_wait_count() |
グラフとまだ対話する外部エンティティーを登録するために使用されます。 ルートタスクの ref_count をインクリメントします。 |
void decrement_wait_count() |
グラフと対話した外部エンティティーを登録解除するために使用されます。 ルートタスクの ref_count をデクリメントします。 |
template< typename Receiver, typename Body > void run( Receiver &r, Body body ) |
このメソッドは、ボディーを実行し、その出力を特定のレシーバーに格納するタスクをスポーンします。タスクはグラフのルートタスクの子として作成されるため、このタスクが完了するまで wait_for_all はリターンしません。 r.try_put( body() ) を呼び出すタスクをキューに入れます。タスクが完了するのを待ちません。スポーンされるタスクは、ルートタスクの子です。 |
template< typename Body > void run( Body body ) |
このメソッドは、グラフのルートタスクの子として実行するタスクをスポーンします。このスポーンされたタスクが完了するまで、wait_for_all への呼び出しはリターンしません。 body() を呼び出すタスクをキューに入れます。タスクが完了するのを待ちません。 |
void wait_for_all() |
ルートタスクに関連付けられているすべてのタスクが完了するまで待ちます。decrement_wait_count 呼び出しの数は increment_wait_count 呼び出しの数と同じになります。ルートタスクの wait_for_all を呼び出すため、スレッドを呼び出すとブロック中にワークスチールを行うことになります。 |
task *root_task() |
戻り値: フローグラフのルートタスクのポインター。 |
bool is_cancelled() |
戻り値: wait_for_all() の最後の呼び出し中にグラフがキャンセルされた場合は true。その他の場合は false。 キャンセルの説明は、task_group_context を参照してください。 |
bool exception_thrown() |
戻り値: wait_for_all() の最後の呼び出し中に例外がスローされた場合は true。その他の場合は false。 例外処理の詳細は、「例外」セクションを参照してください。 |
void reset(reset_flags f = rf_reset_protocol) |
reset() のフラグは、ビット単位の OR と組み合わせることができます。 キャンセルの説明は、task_group_context を参照してください。例外処理の詳細は、「例外」セクションを参照してください。 |
フラグ | 説明 |
---|---|
rf_reset_protocol |
すべてのエッジは push 状態に切り替えられますが、すべてのバッファーは空になり、ノードの内部状態は再初期化されます。reset() の呼び出しはすべて、これらのアクションを行います。 |
rf_reset_bodies |
ボディーを含むノードが作成されるとき、コンストラクターで指定されたボディーはコピーされ保存されます。rf_reset_bodies が指定された場合、ノードの現在のボディーは削除され、構築中に保存されたボディーのコピーに置換されます。 注意ボディーが外部コンポーネント (ファイル記述子など) を持つ状態を含む場合、ボディー置換後のグラフの再実行でノードの動作が変わることがあります。この場合、ノードを再作成する必要があります。 |
rf_clear_edges |
すべてのエッジをグラフから削除します。 |