Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Zasady harmonogramu umożliwiają kontrolowanie strategii używanej przez harmonogram podczas zarządzania zadaniami. W tym temacie pokazano, jak za pomocą zasad harmonogramu zwiększyć priorytet wątku zadania, które wyświetla wskaźnik postępu w konsoli.
Przykład użycia niestandardowych zasad harmonogramu razem z agentami asynchronicznymi znajduje się w temacie How to: Create Agents that Use Specific Scheduler Policies (Jak utworzyć agentów korzystających z określonych zasad harmonogramu).
Przykład
Poniższy przykład wykonuje dwa zadania równolegle. Pierwsze zadanie oblicza n numerFibonacciego . Drugie zadanie wyświetla wskaźnik postępu w konsoli.
Pierwsze zadanie używa rekursywnej dekompozycji do obliczenia liczby Fibonacciego. Oznacza to, że każde zadanie cyklicznie tworzy podzadania w celu obliczenia ogólnego wyniku. Zadanie korzystające z dekompozycji cyklicznego może używać wszystkich dostępnych zasobów, a tym samym zagłodzać inne zadania. W tym przykładzie zadanie, które wyświetla wskaźnik postępu, może nie otrzymać czasu dostępu do zasobów obliczeniowych.
Aby udostępnić zadanie, które wyświetla komunikat o postępie sprawiedliwego dostępu do zasobów obliczeniowych, w tym przykładzie użyto kroków opisanych w temacie How to: Manage a Scheduler Instance to create a scheduler instance that has a custom policy (Jak zarządzać wystąpieniem harmonogramu w celu utworzenia wystąpienia harmonogramu z zasadami niestandardowymi). Zasady niestandardowe określają priorytet wątku jako klasę o najwyższym priorytcie.
W tym przykładzie użyto klas concurrency::call i concurrency::timer w celu wydrukowania wskaźnika postępu. Te klasy mają wersje swoich konstruktorów, które przyjmują odwołanie do obiektu współbieżności::Scheduler , który je planuje. W przykładzie użyto domyślnego harmonogramu, aby zaplanować zadanie, które oblicza liczbę Fibonacciego i wystąpienie harmonogramu, aby zaplanować zadanie, które wyświetla wskaźnik postępu.
Aby zilustrować korzyści wynikające z używania harmonogramu z zasadami niestandardowymi, ten przykład wykonuje zadanie ogólne dwa razy. W przykładzie użyto domyślnego harmonogramu, aby zaplanować oba zadania. W tym przykładzie użyto domyślnego harmonogramu, aby zaplanować pierwsze zadanie, oraz harmonogram, który ma niestandardowe zasady, 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);
}
W tym przykładzie są generowane następujące dane wyjściowe.
Default scheduler:
...........................................................................done
Scheduler that has a custom policy:
...........................................................................done
Mimo że oba zestawy zadań generują ten sam wynik, wersja, która używa zasad niestandardowych, umożliwia zadanie, które wyświetla wskaźnik postępu w celu uruchomienia z podwyższonym priorytetem, tak aby zachowywał się szybciej.
Kompilowanie kodu
Skopiuj przykładowy kod i wklej go w projekcie programu Visual Studio lub wklej go w pliku o nazwie scheduler-policy.cpp
, a następnie uruchom następujące polecenie w oknie wiersza polecenia programu Visual Studio.
cl.exe /EHsc scheduler-policy.cpp
Zobacz też
Zasady harmonogramu
Instrukcje: zarządzanie wystąpieniem harmonogramu
Instrukcje: tworzenie agentów korzystających ze specjalnych zasad harmonogramu