次の方法で共有


方法: スケジューラ インスタンスを管理する

スケジューラ インスタンスにより、特定のスケジューリング ポリシーと各種の作業負荷を関連付けることができます。 このトピックには、スケジューラ インスタンスを作成および管理する方法を示す 2 つの基本的な例が含まれています。

例では、既定のスケジューラ ポリシーを使用するスケジューラを作成します。 カスタム ポリシーを使用するスケジューラを作成する例については、「方法: 特定のスケジューラ ポリシーを指定する」を参照してください。

アプリケーションのスケジューラ インスタンスを管理するには

  1. スケジューラが使用するポリシー値が含まれる concurrency::SchedulerPolicy オブジェクトを作成します。

  2. concurrency::CurrentScheduler::Create メソッドまたは concurrency::Scheduler::Create メソッドを呼び出して、スケジューラ インスタンスを作成します。

    Scheduler::Create メソッドを使用する場合は、スケジューラを現在のコンテキストに関連付ける必要があるときに concurrency::Scheduler::Attach メソッドを呼び出します。

  3. CreateEvent 関数を呼び出して、非シグナルの自動リセット イベント オブジェクトのハンドルを作成します。

  4. 作成したイベント オブジェクトのハンドルを concurrency::CurrentScheduler::RegisterShutdownEvent メソッドまたは concurrency::Scheduler::RegisterShutdownEvent メソッドに渡します。 これにより、スケジューラが破棄されるときに設定されるイベントが登録されます。

  5. 現在のスケジューラでスケジュールするタスクを実行します。

  6. concurrency::CurrentScheduler::Detach メソッドを呼び出して現在のスケジューラをデタッチし、以前のスケジューラを現在のスケジューラとして復元します。

    Scheduler::Create メソッドを使用する場合は、concurrency::Scheduler::Release メソッドを呼び出して、Scheduler オブジェクトの参照カウントをデクリメントします。

  7. イベントのハンドルを WaitForSingleObject 関数に渡して、スケジューラがシャットダウンするのを待ちます。

  8. CloseHandle 関数を呼び出して、イベント オブジェクトのハンドルを閉じます。

次のコードに、スケジューラ インスタンスを管理するための 2 つの方法を示します。 どちらの例でも、最初に既定のスケジューラを使用して、現在のスケジューラの一意の識別子を印刷するタスクを実行します。 次に、スケジューラ インスタンスを使用して同じタスクを再び実行します。 最後に、既定のスケジューラを現在のスケジューラとして復元した後、もう一度同じタスクを実行します。

1 つ目の例では、concurrency::CurrentScheduler クラスを使用して、スケジューラ インスタンスを作成し、それを現在のコンテキストに関連付けています。 2 つ目の例では、concurrency::Scheduler クラスを使用して同じタスクを実行しています。 通常は、現在のスケジューラを操作するのに CurrentScheduler クラスを使用します。 Scheduler クラスを使用する 2 つ目の例は、スケジューラを現在のコンテキストに関連付けるタイミングを制御したり、特定のスケジューラを特定のタスクに関連付けたりする場合に有用です。

// scheduler-instance.cpp
// compile with: /EHsc
#include <windows.h>
#include <ppl.h>
#include <iostream>

using namespace concurrency;
using namespace std;

// Prints the identifier of the current scheduler to the console.
void perform_task()
{
   // A task group.
   task_group tasks;

   // Run a task in the group. The current scheduler schedules the task.
   tasks.run_and_wait([] { 
      wcout << L"Current scheduler id: " << CurrentScheduler::Id() << endl;
   });
}

// Uses the CurrentScheduler class to manage a scheduler instance.
void current_scheduler()
{
   // Run the task.
   // This prints the identifier of the default scheduler.
   perform_task();

   // For demonstration, create a scheduler object that uses 
   // the default policy values.
   wcout << L"Creating and attaching scheduler..." << endl;
   CurrentScheduler::Create(SchedulerPolicy());

   // Register to be notified when the scheduler shuts down.
   HANDLE hShutdownEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
   CurrentScheduler::RegisterShutdownEvent(hShutdownEvent);

   // Run the task again.
   // This prints the identifier of the new scheduler.
   perform_task();

   // Detach the current scheduler. This restores the previous scheduler
   // as the current one.
   wcout << L"Detaching scheduler..." << endl;
   CurrentScheduler::Detach();

   // Wait for the scheduler to shut down and destroy itself.
   WaitForSingleObject(hShutdownEvent, INFINITE);

   // Close the event handle.
   CloseHandle(hShutdownEvent);

   // Run the sample task again.
   // This prints the identifier of the default scheduler.
   perform_task();
}

// Uses the Scheduler class to manage a scheduler instance.
void explicit_scheduler()
{
   // Run the task.
   // This prints the identifier of the default scheduler.
   perform_task();

   // For demonstration, create a scheduler object that uses 
   // the default policy values.
   wcout << L"Creating scheduler..." << endl;
   Scheduler* scheduler = Scheduler::Create(SchedulerPolicy());

   // Register to be notified when the scheduler shuts down.
   HANDLE hShutdownEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
   scheduler->RegisterShutdownEvent(hShutdownEvent);

   // Associate the scheduler with the current thread.
   wcout << L"Attaching scheduler..." << endl;
   scheduler->Attach();

   // Run the sample task again.
   // This prints the identifier of the new scheduler.
   perform_task();

   // Detach the current scheduler. This restores the previous scheduler
   // as the current one.
   wcout << L"Detaching scheduler..." << endl;
   CurrentScheduler::Detach();

   // Release the final reference to the scheduler. This causes the scheduler
   // to shut down after all tasks finish.
   scheduler->Release();

   // Wait for the scheduler to shut down and destroy itself.
   WaitForSingleObject(hShutdownEvent, INFINITE);

   // Close the event handle.
   CloseHandle(hShutdownEvent);

   // Run the sample task again.
   // This prints the identifier of the default scheduler.
   perform_task();
}

int wmain()
{
   // Use the CurrentScheduler class to manage a scheduler instance.
   wcout << L"Using CurrentScheduler class..." << endl << endl;
   current_scheduler();

   wcout << endl << endl;

   // Use the Scheduler class to manage a scheduler instance.
   wcout << L"Using Scheduler class..." << endl << endl;
   explicit_scheduler();
}

この例を実行すると、次の出力が生成されます。

Using CurrentScheduler class...

Current scheduler id: 0
Creating and attaching scheduler...
Current scheduler id: 1
Detaching scheduler...
Current scheduler id: 0

Using Scheduler class...

Current scheduler id: 0
Creating scheduler...
Attaching scheduler...
Current scheduler id: 2
Detaching scheduler...
Current scheduler id: 0

コードのコンパイル

コード例をコピーし、Visual Studio プロジェクトに貼り付けるか、scheduler-instance.cpp という名前のファイルに貼り付けてから、Visual Studio のコマンド プロンプト ウィンドウで次のコマンドを実行します。

cl.exe /EHsc scheduler-instance.cpp

関連項目

スケジューラ インスタンス
方法: 特定のスケジューラ ポリシーを指定する