Поделиться через


Практическое руководство. Управление экземпляром планировщика

Экземпляры планировщика позволяют связывать конкретные политики планирования с различными видами рабочих нагрузок.В этом разделе содержатся два базовых примера, демонстрирующих создание экземпляра планировщика и управление им.

В этих примерах создаются планировщики, использующие политики планировщика по умолчанию.Пример создания планировщика, использующего пользовательскую политику, см. в разделе Практическое руководство. Задание определенных политик планировщика.

Управление экземпляром планировщика в приложении

  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, чтобы закрыть дескриптор объекта события.

Пример

В следующем фрагменте кода показаны два способа управления экземпляром планировщика.В каждом примере для выполнения задачи, выводящей уникальный идентификатор текущего планировщика, сначала используется планировщик по умолчанию.Затем в каждом примере для повторного выполнения той же задачи используется экземпляр планировщика.Наконец, в каждом примере планировщик по умолчанию восстанавливается в качестве текущего и еще раз выполняет эту задачу.

В первом примере используется concurrency::CurrentScheduler класса для создания экземпляра планировщика заданий и связывания его с текущим контекстом.Во втором примере используется concurrency::Scheduler класса для выполнения этой задачи.Как правило, класс CurrentScheduler используется для работы с текущим планировщиком.Сценарий, описанный во втором примере, в котором используется класс Scheduler, нужно использовать, если необходимо контролировать время связывания планировщика с текущим контекстом или связывать конкретные планировщики с конкретными задачами.

// 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 или вставьте его в файл с именем Планировщик instance.cpp и запустите следующую команду в окне командной строки Visual Studio.

cl.exe /EHsc scheduler-instance.cpp

См. также

Задачи

Практическое руководство. Задание определенных политик планировщика

Основные понятия

Экземпляры планировщика