Partager via


Comment : gérer une instance de planificateur

Les instances du planificateur vous permettent d'associer des stratégies de planification spécifiques à différents genres de charges de travail. Cette rubrique contient deux exemples de base qui indiquent comment créer et gérer une instance du planificateur.

Les exemples créent des planificateurs qui utilisent les stratégies du planificateur par défaut. Pour obtenir un exemple qui crée un planificateur qui utilise une stratégie personnalisée, consultez Comment : spécifier des stratégies de planificateur.

Pour gérer une instance du planificateur dans votre application

  1. Créez un objet Concurrency::SchedulerPolicy qui contient les valeurs de stratégie que le planificateur doit utiliser.

  2. Appelez la méthode Concurrency::CurrentScheduler::Create ou la méthode Concurrency::Scheduler::Create pour créer une instance du planificateur.

    Si vous utilisez la méthode Scheduler::Create, appelez la méthode Concurrency::Scheduler::Attach lorsque vous devez associer le planificateur au contexte actuel.

  3. Appelez la fonction CreateEvent pour créer un handle vers un objet événement à réinitialisation automatique non signalé.

  4. Passez le handle vers l'objet événement que vous venez de créer à la méthode Concurrency::CurrentScheduler::RegisterShutdownEvent ou Concurrency::Scheduler::RegisterShutdownEvent. Cela enregistre l'événement à définir lors de la destruction du planificateur.

  5. Effectuez les tâches que vous voulez que le planificateur actuel planifie.

  6. Appelez la méthode Concurrency::CurrentScheduler::Detach pour détacher le planificateur actuel et restaurer le planificateur précédent comme planificateur actuel.

    Si vous utilisez la méthode Scheduler::Create, appelez la méthode Concurrency::Scheduler::Release pour décrémenter le décompte de référence de l'objet Scheduler.

  7. Passez le handle vers l'événement à la fonction WaitForSingleObject pour attendre que le planificateur s'arrête.

  8. Appelez la fonction CloseHandle pour fermer le handle vers l'objet événement.

Exemple

Le code suivant illustre deux manières de gérer une instance du planificateur. Chaque exemple utilise d'abord le planificateur par défaut pour effectuer une tâche qui imprime l'identificateur unique du planificateur actuel. Chaque exemple utilise ensuite une instance du planificateur pour effectuer de nouveau la même tâche. Pour finir, chaque exemple restaure le planificateur par défaut comme planificateur actuel et exécute la tâche une fois de plus.

Le premier exemple utilise la classe Concurrency::CurrentScheduler pour créer une instance du planificateur et l'associer au contexte actuel. Le deuxième exemple utilise la classe Concurrency::Scheduler pour effectuer la même tâche. En général, la classe CurrentScheduler s'utilise avec le planificateur actuel. Le deuxième exemple, qui utilise la classe Scheduler, est utile lorsque vous voulez contrôler le moment où le planificateur est associé au contexte actuel ou lorsque vous voulez associer des planificateurs spécifiques à des tâches spécifiques.

// 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();
}

Cet exemple génère la sortie suivante :

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

Compilation du code

Copiez l'exemple de code et collez-le dans un projet Visual Studio, ou collez-le dans un fichier nommé scheduler-instance.cpp puis exécutez la commande suivante dans une fenêtre d'invite de commandes Visual Studio 2010.

cl.exe /EHsc scheduler-instance.cpp

Voir aussi

Tâches

Comment : spécifier des stratégies de planificateur

Autres ressources

Instances de planificateur