スケジューラ インスタンス
このドキュメントでは、同時実行ランタイムでのスケジューラ インスタンスの役割、および concurrency::Scheduler クラスと concurrency::CurrentScheduler クラスを使用して、スケジューラ インスタンスを作成して管理する方法について説明します。 スケジューラ インスタンスは、明示的なスケジューリング ポリシーを特定の種類のワークロードに関連付ける必要がある場合に便利です。 たとえば、昇格したスレッド優先順位で一部のタスクを実行するようにスケジューラ インスタンスを 1 つ作成し、他のタスクについては既定のスケジューラを使用して通常のスレッド優先順位で実行することができます。
ヒント
コンカレンシー ランタイムには既定のスケジューラが用意されているため、アプリケーションにスケジューラを作成する必要はありません。 タスク スケジューラを使用すると、アプリケーションのパフォーマンスを微調整できるため、同時実行ランタイムを初めて使用する場合は、並列パターン ライブラリ (PPL) または非同期エージェント ライブラリから始めることをお勧めします。
セクション
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 に設定されます)。 また、concurrency::Scheduler::Reference メソッドを使用して、Scheduler
オブジェクトの参照カウントをインクリメントすることもできます。
concurrency::CurrentScheduler::Detach メソッドを呼び出して現在のスケジューラをデタッチするか、concurrency::Scheduler::Release メソッドを呼び出すと、参照カウントはランタイムによってデクリメントされます。 参照カウントが 0 になり、スケジュールされたタスクがすべて完了すると、Scheduler
オブジェクトはランタイムによって破棄されます。 実行中のタスクによる現在のスケジューラの参照カウントのインクリメントは許可されています。 したがって、参照カウントが 0 になり、タスクによってその参照カウントがインクリメントされると、ランタイムによる Scheduler
オブジェクトの破棄は、その参照カウントが再び 0 になって、すべてのタスクが終了するまで行われません。
ランタイムでは、コンテキストごとに 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
オブジェクトの破棄は、すべてのタスクが完了するまで行われません。このため、concurrency::Scheduler::RegisterShutdownEvent メソッドまたは concurrency::CurrentScheduler::RegisterShutdownEvent メソッドを使用して、Scheduler
オブジェクトが破棄されたときに通知を受け取ることができます。 これは、Scheduler
オブジェクトによってスケジュールされたすべてのタスクが終了するのを待たなければならないときに役に立ちます。
[トップ]
メソッドと機能
このセクションでは、CurrentScheduler
クラスと Scheduler
クラスの重要なメソッドの概要を示します。
CurrentScheduler
クラスは、現在のコンテキスト上で使用するスケジューラを作成するためのヘルパーと考えてください。 Scheduler
クラスを使用すると、別のコンテキストに属するスケジューラを制御できます。
次の表に、CurrentScheduler
クラスで定義されている重要なメソッドを示します。
Method | 説明 |
---|---|
作成 | 指定されたポリシーを使用し、それを現在のコンテキストに関連付ける Scheduler オブジェクトを作成します。 |
Get | 現在のコンテキストに関連付けられている Scheduler オブジェクトへのポインターを取得します。 このメソッドでは、Scheduler オブジェクトの参照カウントはインクリメントされません。 |
[デタッチ] | 現在のスケジューラを現在のコンテキストからデタッチし、以前のスケジューラを現在のスケジューラとして設定します。 |
RegisterShutdownEvent | 現在のスケジューラが破棄されたときにランタイムによって設定されるイベントを登録します。 |
CreateScheduleGroup | 現在のスケジューラに concurrency::ScheduleGroup オブジェクトを作成します。 |
ScheduleTask | 軽量タスクを現在のスケジューラのスケジュール キューに追加します。 |
GetPolicy | 現在のスケジューラに関連付けられているポリシーのコピーを取得します。 |
次の表に、Scheduler
クラスで定義されている重要なメソッドを示します。
Method | 説明 |
---|---|
作成 | 指定されたポリシーを使用する Scheduler オブジェクトを作成します。 |
[アタッチ] | Scheduler オブジェクトを現在のコンテキストに関連付けます。 |
リファレンス | Scheduler オブジェクトの参照カウンターをインクリメントします。 |
リリース | Scheduler オブジェクトの参照カウンターをデクリメントします。 |
RegisterShutdownEvent | Scheduler オブジェクトが破棄されたときにランタイムによって設定されるイベントを登録します。 |
CreateScheduleGroup | Scheduler オブジェクトに concurrency::ScheduleGroup オブジェクトを作成します。 |
ScheduleTask | Scheduler オブジェクトから軽量タスクをスケジュールします。 |
GetPolicy | Scheduler オブジェクトに関連付けられているポリシーのコピーを取得します。 |
SetDefaultSchedulerPolicy | 既定のスケジューラの作成時に使用されるランタイムのポリシーを設定します。 |
ResetDefaultSchedulerPolicy | 既定のポリシーを、SetDefaultSchedulerPolicy の呼び出し前にアクティブだったものに復元します。 この呼び出しの後に既定のスケジューラが作成された場合、ランタイムは既定のポリシー設定を使用してスケジューラを作成します。 |
[トップ]
例
スケジューラ インスタンスを作成および管理する方法の基本的な例については、「方法: スケジューラ インスタンスを管理する」を参照してください。