最初から再割り当てを行うよりも、タスク・オブジェクトを再利用するほうが多くの場合効率的です。親は継続、またはプレデセッサーの 1 つとしてよく再利用されます。
オーバーラップの規則: 再利用されるタスク t は、t.execute() の前の呼び出しがまだ実行中の間は t.execute() が再実行される状況で利用してはなりません。ライブラリーのデバッグバージョンは、この規則の違反を検出します。
例えば、t.execute() は t を再利用した後に直接作成してはなりません。代わりに、t.execute() は t のポインターを返して、t.execute() が完了した後、t が作成されるようにします。
メンバー | 説明 |
---|---|
void recycle_as_continuation() |
要件: execute() メソッドの実行中に呼び出されること。 再利用するタスクの refcount は、n (n は継続タスクのプレデセッサーの数) に設定する必要があります。 注意呼び出し元は、execute() メソッドがリターンするまでタスクの refcount が 0 にならないことを保証する必要があります。保証できない場合、代わりに recycle_as_safe_continuation() メソッドを使用して、refcount を n+1 に設定してください。 次の場合、タスク t で競合状態が発生します。 t.execute() が t を継続として再利用する。 継続が t.execute() がリターンする前にすべて完了するプレデセッサーを持っている。 このため、オリジナルの t.execute() の実行中に再利用される t が暗黙的に作成され、オーバーラップの規則に違反してしまいます。 recycle_as_continuation() を使用するパターンは通常、t.execute() が明示的にそのプレデセッサーを作成する代わりにプレデセッサーの 1 つのポインターを返すことにより、競合状態を回避します。スケジューラーは、t.execute() がリターンした後に暗黙的にそのプレデセッサーを作成して、再利用される t が早めに再実行しないことを保証します。 効果: execute() メソッドがリターンしたときに this を破棄しません。 |
void recycle_as_safe_continuation() |
要件: execute() メソッドの実行中に呼び出されること。 再利用するタスクの refcount は、n+1 (n は継続タスクのプレデセッサーの数) に設定する必要があります。+1 は、タスクが再利用されることを表します。 効果: execute() メソッドがリターンしたときに this を破棄しません。 refcount に追加される +1 によって execute() のオリジナルの呼び出しが完了するまで継続が実行されないため、このメソッドは recycle_as_continuation で説明された競合状態を回避します。 |
void recycle_as_child_of( task& new_successor ) |
要件: execute() メソッドの実行中に呼び出されること。 効果: this を new_successor のプレデセッサーとして、execute() メソッドがリターンしたときに破棄しません。 |