Sdílet prostřednictvím


Postupy: Určení specifických zásad plánovače

Zásady plánovač umožňuje určit strategii, kterou Plánovač používá při správě úkolů.Toto téma ukazuje, jak pomocí zásad Plánovač zvýšit prioritu podprocesu úkolu zobrazí indikátor průběhu na konzolu.

Pro příklad, který používá vlastní plánovač zásady a asynchronní agenti, viz Postupy: Vytváření agentů využívajících specifické zásady plánovače.

Příklad

Následující příklad provede dva úkoly současně.První úkol vypočítá nth Fibonacciho číslo.Druhý úkol zobrazí indikátor průběhu v konzole.

První úkol používá rekurzivní rozkladu pro výpočet Fibonacciho číslo.To znamená že každý úkolů rekurzivně vytvoří dílčích úkolů, chcete-li vypočítat celkový výsledek.Úkol, který používá rekurzivní rozkladu může použít všechny dostupné prostředky a tím starve jiných úkolů.V tomto příkladu nemusí úkol, který se zobrazí indikátor průběhu zobrazí včasný přístup k výpočetní zdroje.

Stanovit úkol, který vytiskne zprávu průběh spravedlivý přístup k výpočetním zdrojům v tomto příkladu kroky, které jsou popsány v Postupy: Správa instance plánovače k vytvoření instance Plánovač, který má vlastní zásady.Vlastní zásada určuje prioritu podprocesu se s nejvyšší prioritou.

V tomto příkladu concurrency::call a concurrency::timer tříd průběhu tisku.Tyto třídy mají verze jejich konstruktory, které nepřijímají odkaz na concurrency::Scheduler objekt, který je plánuje.Příklad používá výchozí plánovač naplánování úlohy, která vypočítává Fibonacciho číslo a instanci plánovače naplánovat úlohu, která zobrazí indikátor průběhu.

Pro ilustraci výhody používání plánovače, který má vlastní zásady, v tomto příkladu provede obecný úkol dvakrát.V prvním příkladu výchozí plánovač oba úkoly naplánovat.Příklad poté používá výchozí plánovač první úkol naplánovat a Plánovač, který má vlastní zásady druhého úkolu.

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

Tento příklad vytvoří následující výstup.

  

Přestože obě sady úkolů mají stejný výsledek, verze, která používá vlastní zásadu umožňuje úkol, který se zobrazí indikátor průběhu spuštění při zvýšení priority tak, aby se chová více responsively.

Probíhá kompilace kódu

Zkopírovat ukázkový kód a vložit jej do projektu sady Visual Studio nebo vložit do souboru s názvem Plánovač policy.cpp a potom spusťte následující příkaz v okně Příkazový řádek Visual Studio.

cl.exe /EHsc scheduler-policy.cpp

Viz také

Úkoly

Postupy: Správa instance plánovače

Postupy: Vytváření agentů využívajících specifické zásady plánovače

Koncepty

Zásady plánovače