Compartir a través de


Cómo: Administrar una instancia del programador

Las instancias del Programador permiten asociar directivas de programación concretas con varios tipos de cargas de trabajo. Este tema contiene dos ejemplos básicos que muestran cómo crear y administrar una instancia del programador.

En los ejemplos se crean programadores que usan las directivas del programador predeterminado. Para ver un ejemplo que crea un programador que utiliza una directiva personalizada, consulte Procedimiento para especificar directivas de Scheduler concretas.

Para administrar una instancia del programador en su aplicación

  1. Cree un objeto concurrency::SchedulerPolicy que contenga los valores de directiva que debe usar el programador.

  2. Llame al método concurrency::CurrentScheduler::Create o al método concurrency::Scheduler::Create para crear una instancia del programador.

    Si usa el método Scheduler::Create, llame al método concurrency::Scheduler::Attach cuando necesite asociar el programador al contexto actual.

  3. Llame a la función CreateEvent para crear un controlador para un objeto de evento de restablecimiento automático no señalado.

  4. Pase el identificador del objeto de evento recién creado al método concurrency::CurrentScheduler::RegisterShutdownEvent o al método concurrency::Scheduler::RegisterShutdownEvent. De esta forma se registra el evento que se debe establecer cuando se destruya el programador.

  5. Realice las tareas que desea que programe el programador actual.

  6. Llame al método concurrency::CurrentScheduler::Detach para desasociar el programador actual y restaurar el programador anterior.

    Si usa el método Scheduler::Create, llame al método concurrency::Scheduler::Release para reducir el recuento de referencias del objeto Scheduler.

  7. Pase el controlador del evento a la función WaitForSingleObject para esperar a que el programador se cierre.

  8. Llame a la función CloseHandle para cerrar el controlador del objeto de evento.

Ejemplo

En el siguiente código se muestran dos maneras de administrar una instancia del programador. En cada ejemplo se usa primero el programador predeterminado para realizar una tarea que imprima el identificador único del programador actual. A continuación, se usa una instancia del programador para realizar la misma tarea de nuevo. Finalmente, en cada ejemplo se restaura el programador predeterminado como el actual y se realiza la tarea una vez más.

En el primer ejemplo, se usa la clase concurrency::CurrentScheduler para crear una instancia del programador y asociarla al contexto actual. En el segundo ejemplo, se usa la clase concurrency::Scheduler para realizar la misma tarea. Normalmente, la clase CurrentScheduler se usa con el programador actual. El segundo ejemplo, que usa la clase Scheduler, es útil si se desea controlar cuándo está asociado el programador al contexto actual o si se desea asociar programadores concretos a tareas concretas.

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

Este ejemplo produce el siguiente resultado:

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

Compilar el código

Copie el código de ejemplo y péguelo en un proyecto de Visual Studio o en un archivo denominado scheduler-instance.cpp y, después, ejecute el siguiente comando en una ventana del símbolo del sistema de Visual Studio.

cl.exe /EHsc scheduler-instance.cpp

Consulte también

Instancias de Scheduler
Procedimiento para especificar directivas de Scheduler concretas