방법: 특정 Scheduler 정책 지정How to: Specify Specific Scheduler Policies

Scheduler 정책을 사용 하면 스케줄러에서 작업을 관리할 때 사용 하는 전략을 제어할 수 있습니다.Scheduler policies let you control the strategy that the scheduler uses when it manages tasks. 이 항목에서는 스케줄러 정책을 사용 하 여 진행률 표시기를 콘솔에 출력 하는 작업의 스레드 우선 순위를 늘리는 방법을 보여 줍니다.This topic shows how to use a scheduler policy to increase the thread priority of a task that prints a progress indicator to the console.

비동기 에이전트와 함께 사용자 지정 스케줄러 정책을 사용 하는 예제는 방법: 특정 스케줄러 정책을 사용 하는 에이전트 만들기를 참조 하세요.For an example that uses custom scheduler policies together with asynchronous agents, see How to: Create Agents that Use Specific Scheduler Policies.

예제Example

다음 예에서는 두 작업을 병렬로 수행 합니다.The following example performs two tasks in parallel. 첫 번째 작업은 n번째 피보나치 수를 계산 합니다.The first task computes the nth Fibonacci number. 두 번째 작업은 진행률 표시기를 콘솔에 출력 합니다.The second task prints a progress indicator to the console.

첫 번째 태스크는 재귀 분해를 사용 하 여 피보나치 수를 계산 합니다.The first task uses recursive decomposition to compute the Fibonacci number. 즉, 각 작업은 재귀적으로 하위 작업을 만들어 전체 결과를 계산 합니다.That is, each task recursively creates subtasks to compute the overall result. 재귀적 분해를 사용 하는 작업은 사용 가능한 모든 리소스를 사용 하 여 다른 작업을 결핍 수 있습니다.A task that uses recursive decomposition might use all available resources, and thereby starve other tasks. 이 예제에서 진행률 표시기를 인쇄 하는 작업은 컴퓨팅 리소스에 대 한 시기 적절 한 액세스를 수신 하지 못할 수 있습니다.In this example, the task that prints the progress indicator might not receive timely access to computing resources.

진행 메시지를 인쇄 하는 작업을 제공 하 여 컴퓨팅 리소스에 대 한 공평 한 액세스를 제공 하기 위해이 예제에서는 방법: 스케줄러 인스턴스 관리 에 설명 된 단계를 사용 하 여 사용자 지정 정책을 포함 하는 스케줄러 인스턴스를 만듭니다.To provide the task that prints a progress message fair access to computing resources, this example uses steps that are described in How to: Manage a Scheduler Instance to create a scheduler instance that has a custom policy. 사용자 지정 정책은 우선 순위가 가장 높은 클래스가 되도록 스레드 우선 순위를 지정 합니다.The custom policy specifies the thread priority to be the highest priority class.

이 예제에서는 concurrency:: callconcurrency:: timer 클래스를 사용 하 여 진행률 표시기를 인쇄 합니다.This example uses the concurrency::call and concurrency::timer classes to print the progress indicator. 이러한 클래스에는 예약 된 concurrency:: Scheduler 개체에 대 한 참조를 사용 하는 생성자 버전이 있습니다.These classes have versions of their constructors that take a reference to a concurrency::Scheduler object that schedules them. 이 예제에서는 기본 스케줄러를 사용 하 여 피보나치 수를 계산 하는 작업을 예약 하 고 스케줄러 인스턴스를 사용 하 여 진행률 표시기를 인쇄 하는 작업을 예약 합니다.The example uses the default scheduler to schedule the task that computes the Fibonacci number and the scheduler instance to schedule the task that prints the progress indicator.

사용자 지정 정책이 있는 스케줄러를 사용 하는 이점을 보여 주기 위해이 예에서는 전체 작업을 두 번 수행 합니다.To illustrate the benefits of using a scheduler that has a custom policy, this example performs the overall task two times. 이 예에서는 먼저 기본 스케줄러를 사용 하 여 두 작업을 예약 합니다.The example first uses the default scheduler to schedule both tasks. 그런 다음이 예제에서는 기본 스케줄러를 사용 하 여 첫 번째 작업을 예약 하 고, 두 번째 작업을 예약 하는 사용자 지정 정책이 있는 스케줄러를 사용 합니다.The example then uses the default scheduler to schedule the first task, and a scheduler that has a custom policy to schedule the second task.

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

이 예제의 결과는 다음과 같습니다.This example produces the following output.

Default scheduler:
...........................................................................done
Scheduler that has a custom policy:
...........................................................................done

두 작업 집합 모두 동일한 결과를 생성 하지만, 사용자 지정 정책을 사용 하는 버전은 진행률 표시기를 인쇄 하는 작업이 승격 된 우선 순위로 실행 되도록 하 여 더 반응 동작 하도록 합니다.Although both sets of tasks produce the same result, the version that uses a custom policy enables the task that prints the progress indicator to run at an elevated priority so that it behaves more responsively.

코드 컴파일Compiling the Code

예제 코드를 복사 하 여 Visual Studio 프로젝트에 붙여넣거나 라는 파일에 붙여 넣은 scheduler-policy.cpp 후 Visual Studio 명령 프롬프트 창에서 다음 명령을 실행 합니다.Copy the example code and paste it in a Visual Studio project, or paste it in a file that is named scheduler-policy.cpp and then run the following command in a Visual Studio Command Prompt window.

cl.exe/EHsc scheduler-policycl.exe /EHsc scheduler-policy.cpp

참고 항목See also

스케줄러 정책Scheduler Policies
방법: 스케줄러 인스턴스 관리How to: Manage a Scheduler Instance
방법: 특정 스케줄러 정책을 사용 하는 에이전트 만들기How to: Create Agents that Use Specific Scheduler Policies