Compartilhar via


Como: Especificar políticas específicas de agendador

As políticas de agendador permitem controlar a estratégia que o agendador usa quando gerencia tarefas.Este tópico mostra como usar uma política de agendador para aumentar a prioridade de segmento de uma tarefa que imprimir um indicador de progresso no console.

Para um exemplo que usa diretivas personalizados de agendador juntamente com agentes assíncronas, consulte Como: Crie os agentes usando diretivas específicas de agendador.

Exemplo

O exemplo tem duas tarefas paralelamente.A primeira tarefa calcula o número de Fibonacci emth .A segunda tarefa imprime um indicador de progresso no console.

A primeira tarefa usa a decomposição recursiva para calcular o número de Fibonacci.Isto é, cada tarefa cria recursivamente subtarefas para calcular o resultado total.Uma tarefa que usa a decomposição recursiva pode usar os recursos disponíveis, e morre de fome assim outras tarefas.Nesse exemplo, a tarefa que imprime o indicador de progresso não pode receber acesso aos recursos de computação hábil.

Para fornecer a tarefa que lê um acesso forte mensagem de progresso da os recursos de computação, etapas deste exemplo usa o que são descritas em Como: Gerenciar uma instância de agendador para criar uma instância de agendador que tenha uma diretiva personalizado.A diretiva personalizado especifica a prioridade de segmento para ser a classe a maior prioridade.

Este exemplo usa as classes de concurrency::call e de concurrency::timer para imprimir o indicador de progresso.Essas classes têm versões dos construtores que recebem uma referência a um objeto de concurrency::Scheduler que os agende.O exemplo usa o agendador padrão para agendar a tarefa que calcula o número de Fibonacci e a instância de agendador para agendar a tarefa que imprime o indicador de progresso.

Para ilustrar os benefícios do uso de um agendador que tenha uma diretiva personalizado, este exemplo reproduz a tarefa geral duas vezes.O exemplo a seguir primeiro usa o agendador padrão para agendar ambas as tarefas.O exemplo usa o agendador padrão para agendar a primeira tarefa, e um agendador que tenha uma diretiva personalizado para agendar a segunda tarefa.

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

using namespace concurrency;
using namespace std;

// Computes the nth Fibonacci number.
// This function illustrates a lengthy operation and is therefore
// not optimized for performance.
int fibonacci(int n)
{
   if (n < 2)
      return n;

   // Compute the components in parallel.
   int n1, n2;
   parallel_invoke(
      [n,&n1] { n1 = fibonacci(n-1); },
      [n,&n2] { n2 = fibonacci(n-2); }
   );

   return n1 + n2;
}

// Prints a progress indicator while computing the nth Fibonacci number.
void fibonacci_with_progress(Scheduler& progress_scheduler, int n)
{
   // Use a task group to compute the Fibonacci number.
   // The tasks in this group are scheduled by the current scheduler.
   structured_task_group tasks;

   auto task = make_task([n] {
      fibonacci(n);
   });
   tasks.run(task);

   // Create a call object that prints its input to the console.
   // This example uses the provided scheduler to schedule the 
   // task that the call object performs.
   call<wchar_t> c(progress_scheduler, [](wchar_t c) { 
      wcout << c; 
   });

   // Connect the call object to a timer object. The timer object
   // sends a progress message to the call object every 100 ms.
   // This example also uses the provided scheduler to schedule the 
   // task that the timer object performs.
   timer<wchar_t> t(progress_scheduler, 100, L'.', &c, true);
   t.start();

   // Wait for the task that computes the Fibonacci number to finish.
   tasks.wait();

   // Stop the timer.
   t.stop();

   wcout << L"done" << endl;
}

int wmain()
{  
   // Calculate the 38th Fibonacci number.
   const int n = 38;

   // Use the default scheduler to schedule the progress indicator while 
   // the Fibonacci number is calculated in the background.

   wcout << L"Default scheduler:" << endl;
   fibonacci_with_progress(*CurrentScheduler::Get(), n);

   // Now use a scheduler that has a custom policy for the progress indicator.
   // The custom policy specifies the thread priority to the highest 
   // priority class.

   SchedulerPolicy policy(1, ContextPriority, THREAD_PRIORITY_HIGHEST);
   Scheduler* scheduler = Scheduler::Create(policy);

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

   wcout << L"Scheduler that has a custom policy:" << endl;
   fibonacci_with_progress(*scheduler, n);

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

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

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

O exemplo produz a seguinte saída.

  

Embora ambos os conjuntos de tarefas de gerar o mesmo resultado, a versão que usa uma diretiva personalizado permite que a tarefa que imprime o indicador de progresso para executar em uma prioridade superior de modo que se comporta mais interativa.

Compilando o código

Copie o código de exemplo e cole-o em um projeto do Visual Studio, ou cole em um arquivo denominado scheduler-policy.cpp e execute o seguinte comando em uma janela de prompt de comando do Visual Studio.

cl.exe /EHsc scheduler-policy.cpp

Consulte também

Tarefas

Como: Gerenciar uma instância de agendador

Como: Crie os agentes usando diretivas específicas de agendador

Conceitos

Diretivas de agendador