スケジューラ インスタンス
ここでは、同時実行ランタイムでのスケジューラ インスタンスのロールをスケジューラ インスタンスを作成および管理するために concurrency::Scheduler と concurrency::CurrentScheduler クラスを使用する方法を示します。 スケジューラ インスタンスは、明示的なスケジューリング ポリシーを特定の種類の作業負荷に関連付ける場合に役立ちます。 たとえば、昇格したスレッド優先順位で一部のタスクを実行するようにスケジューラ インスタンスを 1 つ作成し、他のタスクについては既定のスケジューラを使用して通常のスレッド優先順位で実行することができます。
ヒント
同時実行ランタイムには既定のスケジューラが備わっているため、アプリケーションでスケジューラを作成する必要はありません。タスク スケジューラではアプリケーションのパフォーマンスを微調整できるため、同時実行ランタイムを初めて使用する場合は、並列パターン ライブラリ (PPL) または非同期エージェント ライブラリから始めることをお勧めします。
セクション
Scheduler クラスおよび CurrentScheduler クラス
スケジューラ インスタンスの作成
スケジューラ インスタンスの有効期間の管理
メソッドおよび機能
例
Scheduler クラスおよび CurrentScheduler クラス
タスク スケジューラにより、アプリケーションは 1 つ以上のスケジューラ インスタンスを使用して作業をスケジュールできます。 concurrency::Scheduler クラスは、スケジューラ インスタンスを表し、タスクのスケジューリングに関連する機能をカプセル化します。
スケジューラにアタッチされるスレッドは、実行コンテキスト、または単にコンテキストと呼ばれます。 現在のコンテキストでは任意の時点に 1 つのスケジューラをアクティブにすることができます。 アクティブ スケジューラは、現在のスケジューラとも呼ばれます。 同時実行ランタイムでは、現在のスケジューラへのアクセスを提供するために concurrency::CurrentScheduler クラスを使用します。 あるコンテキストの現在のスケジューラは、別のコンテキストの現在のスケジューラとは異なる場合があります。 ランタイムでは、現在のスケジューラのプロセス レベルでの表現は提供されません。
通常、現在のスケジューラへのアクセスには CurrentScheduler クラスが使用されます。 Scheduler クラスは、現在のスケジューラ以外のスケジューラを管理する必要がある場合に役立ちます。
次のセクションでは、スケジューラ インスタンスの作成方法および管理方法について説明します。 これらのタスクを示す完全な例については、「方法: スケジューラ インスタンスを管理する」を参照してください。
[トップ]
スケジューラ インスタンスの作成
Scheduler オブジェクトを作成する方法には次の 3 つがあります。
スケジューラが存在しない場合に、ランタイム機能 (たとえば、並列アルゴリズム) を使用して作業を実行すると、ランタイムにより既定のスケジューラが作成される。 既定のスケジューラは、並列処理を開始するコンテキストの現在のスケジューラとなります。
concurrency::CurrentScheduler::Create のメソッドは、特定のポリシーをを現在のコンテキストに関連付けるそのスケジューラを使用する Scheduler オブジェクトを作成します。
concurrency::Scheduler::Create のメソッドは、特定のポリシーを使用するが作成され、現在のコンテキストに関連付ける Scheduler オブジェクトを示します。
ランタイムで既定のスケジューラを作成できるようにすると、すべての同時実行タスクで同じスケジューラを共有できます。 通常は、並列パターン ライブラリ (PPL) または非同期エージェント ライブラリによって提供される機能を使用して並列処理を実行します。 したがって、直接スケジューラを操作してそのポリシーまたは有効期間を制御する必要はありません。 PPL またはエージェント ライブラリを使用すると、スケジューラが存在しない場合には、ランタイムにより既定のスケジューラが作成され、そのスケジューラが各コンテキストの現在のスケジューラとなります。 スケジューラを作成し、それを現在のスケジューラとして設定すると、ランタイムはそのスケジューラを使用してタスクをスケジュールします。 特定のスケジューリング ポリシーが必要な場合に限り、追加のスケジューラ インスタンスを作成してください。 スケジューラに関連するポリシーの詳細については、「スケジューラ ポリシー」を参照してください。
[トップ]
スケジューラ インスタンスの有効期間の管理
ランタイムは、参照カウント メカニズムを使用して Scheduler オブジェクトの有効期間を制御します。
CurrentScheduler::Create メソッドまたは Scheduler::Create メソッドを使用して Scheduler オブジェクトを作成すると、ランタイムにより、そのスケジューラの参照カウントの初期値が 1 に設定されます。 ランタイムは concurrency::Scheduler::Attach のメソッドを呼び出すときに参照カウントをインクリメントします。 Scheduler::Attach メソッドは、Scheduler オブジェクトを現在のコンテキストに関連付けます。 これにより、それが現在のスケジューラとなります。 CurrentScheduler::Create メソッドを呼び出すと、ランタイムにより Scheduler オブジェクトが作成され、そのオブジェクトが現在のコンテキストに関連付けられます (さらに参照カウントが 1 に設定されます)。 また Scheduler オブジェクトの参照カウントをインクリメントするには concurrency::Scheduler::Reference のメソッドを使用できます。
ランタイムでは、現在のスケジューラをデタッチし concurrency::CurrentScheduler::Detach のメソッドを呼び出すデクリメントしましたりまたは concurrency::Scheduler::Release のメソッドを呼び出すときに参照カウントを。 参照カウントが 0 に達すると、スケジュールされたタスクがすべて終了した後、ランタイムにより Scheduler オブジェクトが破棄されます。 実行中のタスクは、現在のスケジューラの参照カウントをインクリメントできます。 したがって、参照カウントが 0 に達し、タスクが参照カウントをインクリメントした場合、参照カウントが再び 0 に達し、すべてのタスクが終了するまで、ランタイムは Scheduler オブジェクトを破棄しません。
ランタイムは、コンテキストごとに Scheduler オブジェクトの内部スタックを保持します。 Scheduler::Attach メソッドまたは CurrentScheduler::Create メソッドを呼び出すと、ランタイムはその Scheduler オブジェクトを現在のコンテキストのスタックにプッシュします。 これにより、それが現在のスケジューラとなります。 CurrentScheduler::Detach を呼び出すと、ランタイムは、現在のコンテキストのスタックから現在のスケジューラをポップし、前のスケジューラを現在のスケジューラとして設定します。
ランタイムは、スケジューラ インスタンスの有効期間を管理する複数の方法を提供します。 次の表に、現在のコンテキストに対してスケジューラを作成またはアタッチするメソッドごとに、現在のコンテキストからスケジューラを解放またはデタッチする適切なメソッドを示します。
作成メソッドまたはアタッチ メソッド |
解放メソッドまたはデタッチ メソッド |
---|---|
CurrentScheduler::Create |
CurrentScheduler::Detach |
Scheduler::Create |
Scheduler::Release |
Scheduler::Attach |
CurrentScheduler::Detach |
Scheduler::Reference |
Scheduler::Release |
不適切な解放メソッドまたはデタッチ メソッドを呼び出すと、ランタイムで未定義の動作が発生します。
ランタイムにより既定のスケジューラが作成される機能 (たとえば、PPL) を使用する場合、そのスケジューラを解放またはデタッチしないでください。 ランタイムは、作成したスケジューラの有効期間を管理します。
すべてのタスクが終了するまで、ランタイムは Scheduler オブジェクトを破棄しません。このため、Scheduler オブジェクトが破棄されると concurrency::Scheduler::RegisterShutdownEvent のメソッドまたは通知を受け取るために concurrency::CurrentScheduler::RegisterShutdownEvent のメソッドを使用できます。 これは Scheduler オブジェクトによりスケジュールされたタスクがすべて終了するのを待機する必要がある場合に活用できます。
[トップ]
メソッドおよび機能
このセクションでは、CurrentScheduler クラスおよび Scheduler クラスの重要なメソッドについて概説します。
CurrentScheduler クラスは、現在のコンテキストで使用するスケジューラを作成するためのヘルパーと考えてください。 Scheduler クラスにより、別のコンテキストに属するスケジューラを制御できます。
次の表に、CurrentScheduler クラスで定義されている重要なメソッドを示します。
方法 |
説明 |
---|---|
指定したポリシーを使用する Scheduler オブジェクトを作成し、それを現在のコンテキストに関連付けます。 |
|
現在のコンテキストに関連付けられている Scheduler オブジェクトへのポインターを取得します。 このメソッドは、Scheduler オブジェクトの参照カウントをインクリメントしません。 |
|
現在のコンテキストから現在のスケジューラをデタッチし、前のスケジューラを現在のスケジューラとして設定します。 |
|
現在のスケジューラが破棄されたときにランタイムが設定するイベントを登録します。 |
|
現在のスケジューラで concurrency::ScheduleGroup オブジェクトを作成します。 |
|
現在のスケジューラのスケジューリング キューに軽量タスクを追加します。 |
|
現在のスケジューラに関連付けられているポリシーのコピーを取得します。 |
次の表に、Scheduler クラスで定義されている重要なメソッドを示します。
方法 |
説明 |
---|---|
指定したポリシーを使用する Scheduler オブジェクトを作成します。 |
|
Scheduler オブジェクトを現在のコンテキストに関連付けます。 |
|
Scheduler オブジェクトの参照カウンターをインクリメントします。 |
|
Scheduler オブジェクトの参照カウンターをデクリメントします。 |
|
Scheduler オブジェクトが破棄されたときにランタイムが設定するイベントを登録します。 |
|
Scheduler オブジェクトで concurrency::ScheduleGroup オブジェクトを作成します。 |
|
Scheduler オブジェクトから軽量タスクをスケジュールします。 |
|
Scheduler オブジェクトに関連付けられているポリシーのコピーを取得します。 |
|
ランタイムが既定のスケジューラを作成したときに、そのランタイムが使用するポリシーを設定します。 |
|
既定のポリシーを、SetDefaultSchedulerPolicy の呼び出し前にアクティブになっていたポリシーに戻します。 この呼び出しの後に既定のスケジューラが作成される場合、ランタイムは既定のポリシー設定を使用してそのスケジューラを作成します。 |
[トップ]
例
スケジューラ インスタンスを作成および管理する方法の基本的な例については、「方法: スケジューラ インスタンスを管理する」を参照してください。