방법: 특정 스케줄러 정책 지정
스케줄러 정책을 사용하면 스케줄러가 작업을 관리할 때 사용하는 전략을 제어할 수 있습니다. 이 항목에서는 스케줄러 정책을 사용하여 진행률 표시기를 콘솔에 출력하는 작업의 스레드 우선 순위를 높이는 방법을 보여 줍니다.
비동기 에이전트와 함께 사용자 지정 스케줄러 정책을 사용하는 예제를 보려면 방법: 특정 스케줄러 정책을 사용하는 에이전트 만들기를 참조하십시오.
예제
다음 예제에서는 두 가지 작업을 병렬로 수행합니다. 첫 번째 작업에서는 n번째 피보나치(Fibonacci) 수를 계산합니다. 두 번째 작업에서는 진행률 표시기를 콘솔에 출력합니다.
첫 번째 작업에서는 재귀적 분해를 사용하여 피보나치(Fibonacci) 수를 계산합니다. 즉, 각 작업은 재귀적으로 하위 작업을 만들어 전체 결과를 계산합니다. 재귀적 분해를 사용하는 작업은 가능한 모든 리소스를 사용하므로 다른 작업에서 리소스를 사용할 수 없게 됩니다. 이 예제의 경우 진행률 표시기를 출력하는 작업이 컴퓨팅 리소스에 적시에 액세스하지 못할 수 있습니다.
이 예제에서는 진행 메시지를 출력하는 작업에서 컴퓨팅 리소스에 공평하게 액세스할 수 있도록 하기 위해 방법: 스케줄러 인스턴스 관리에 설명된 단계를 사용하여 사용자 지정 정책을 포함하는 스케줄러 인스턴스를 만듭니다. 사용자 지정 정책은 스레드 우선 순위가 최고 우선 순위 클래스가 되도록 지정합니다.
이 예제에서는 Concurrency::call 및 Concurrency::timer 클래스를 사용하여 진행률 표시기를 출력합니다. 이러한 클래스에는 일정을 예약하는 Concurrency::Scheduler 개체에 대한 참조를 사용하는 생성자 버전이 있습니다. 이 예제에서는 피보나치(Fibonacci) 수를 계산하는 작업을 예약할 때 기본 스케줄러를 사용하고 진행률 표시기를 출력하는 작업을 예약할 때 스케줄러 인스턴스를 사용합니다.
사용자 지정 정책을 포함하는 스케줄러를 사용할 경우의 이점을 나타내기 위해 이 예제에서는 전체 작업을 두 번 수행합니다. 이 예제에서는 먼저 기본 스케줄러를 사용하여 두 작업을 예약합니다. 그런 다음 기본 스케줄러를 사용하여 첫 번째 작업을 예약하고, 사용자 지정 정책을 포함하는 스케줄러를 사용하여 두 번째 작업을 예약합니다.
// 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);
}
이 예제의 결과는 다음과 같습니다.
Default scheduler:
...........................................................................done
Scheduler that has a custom policy:
...........................................................................done
두 작업 모두 결과는 같지만 사용자 지정 정책을 사용하는 버전의 경우 진행률 표시기를 출력하는 작업을 높은 우선 순위에서 실행할 수 있으므로 작업의 동작 반응성이 향상됩니다.
코드 컴파일
예제 코드를 복사하여 Visual Studio 프로젝트 또는 scheduler-policy.cpp 파일에 붙여넣고 Visual Studio 2010 명령 프롬프트 창에서 다음 명령을 실행합니다.
cl.exe /EHsc scheduler-policy.cpp