Udostępnij za pośrednictwem


Porady: określanie specjalnych zasad harmonogramu

Harmonogram zasady pozwalają kontrolować strategii, używany w harmonogramie podczas zarządzania zadaniami.W tym temacie przedstawiono sposób użycia zasad harmonogramu, aby podwyższyć priorytet wątku zadania, które drukuje wskaźnik postępu do konsoli.

Na przykład używa zasad niestandardowych harmonogram wraz z agentów asynchronicznych, zobacz Porady: tworzenie agentów korzystających ze specjalnych zasad harmonogramu.

Przykład

Poniższy przykład wykonuje dwa zadania równolegle.Pierwsze zadanie oblicza nth fibonacciego.Drugie zadanie drukuje wskaźnik postępu do konsoli.

Pierwsze zadanie używa cykliczne dekompozycji do wyliczenia fibonacciego.Oznacza to, że rekursywnie każdego zadania tworzy podzadania obliczyć wynik ogólny.Zadania, który używa cykliczne rozkładu mogą używać wszystkich dostępnych zasobów, a tym samym GINA innych zadań.W tym przykładzie zadanie, które drukuje wskaźnika postępu może nie otrzymywać odpowiedni dostęp do zasobów komputerowych.

Aby zapewnić zadanie, które drukuje komunikat postępu, sprawiedliwy dostęp do zasobów komputerowych, w tym przykładzie użyto kroków opisanych w Porady: zarządzanie przypadkiem planisty do utworzenia wystąpienia harmonogramu, która ma zasadę niestandardową.Niestandardowe zasady określa priorytet wątku za najwyższy priorytet.

W poniższym przykładzie użyto concurrency::call i concurrency::timer klasy do drukowania wskaźnik postępu.Te klasy mają wersje ich konstruktorów elementów odwołanie do concurrency::Scheduler obiekt, który planuje je.W przykładzie użyto harmonogram domyślny, aby zaplanować zadanie, które oblicza liczbę Fibonacciego i wystąpienia harmonogramu, aby zaplanować zadanie, które drukuje wskaźnik postępu.

Aby zilustrować korzyści z używania harmonogramu, która ma zasadę niestandardową, w tym przykładzie wykonuje ogólne zadanie dwa razy.W przykładzie użyto najpierw harmonogram domyślny do zaplanowania obu zadań.W przykładzie użyto następnie harmonogram domyślny do zaplanowania pierwszego zadania i harmonogram, który ma zasadę niestandardową, aby zaplanować drugie zadanie.

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

Ten przykład generuje następujące wyniki.

  

Chociaż oba zestawy zadań produkcji tego samego rezultatu, wersji, która używa niestandardowych zasad umożliwia zadanie, które drukuje wskaźnik postępu uruchomienie z podniesionymi uprawnieniami priorytetem, tak aby zachowuje się bardziej responsively.

Kompilowanie kodu

Skopiuj przykładowy kod i wklej go w projekcie programu Visual Studio lub wkleić go w pliku o nazwie Harmonogram policy.cpp , a następnie uruchomić następujące polecenie w oknie wiersza polecenia programu Visual Studio.

cl.exe /EHsc scheduler-policy.cpp

Zobacz też

Zadania

Porady: zarządzanie przypadkiem planisty

Porady: tworzenie agentów korzystających ze specjalnych zasad harmonogramu

Koncepcje

Zasady harmonogramu