다음을 통해 공유


방법: 특정 스케줄러 정책 지정

스케줄러 정책을 사용하면 스케줄러가 작업을 관리할 때 사용하는 전략을 제어할 수 있습니다. 이 항목에서는 스케줄러 정책을 사용하여 진행률 표시기를 콘솔에 출력하는 작업의 스레드 우선 순위를 높이는 방법을 보여 줍니다.

비동기 에이전트와 함께 사용자 지정 스케줄러 정책을 사용하는 예제를 보려면 방법: 특정 스케줄러 정책을 사용하는 에이전트 만들기를 참조하십시오.

예제

다음 예제에서는 두 가지 작업을 병렬로 수행합니다. 첫 번째 작업에서는 n번째 피보나치(Fibonacci) 수를 계산합니다. 두 번째 작업에서는 진행률 표시기를 콘솔에 출력합니다.

첫 번째 작업에서는 재귀적 분해를 사용하여 피보나치(Fibonacci) 수를 계산합니다. 즉, 각 작업은 재귀적으로 하위 작업을 만들어 전체 결과를 계산합니다. 재귀적 분해를 사용하는 작업은 가능한 모든 리소스를 사용하므로 다른 작업에서 리소스를 사용할 수 없게 됩니다. 이 예제의 경우 진행률 표시기를 출력하는 작업이 컴퓨팅 리소스에 적시에 액세스하지 못할 수 있습니다.

이 예제에서는 진행 메시지를 출력하는 작업에서 컴퓨팅 리소스에 공평하게 액세스할 수 있도록 하기 위해 방법: 스케줄러 인스턴스 관리에 설명된 단계를 사용하여 사용자 지정 정책을 포함하는 스케줄러 인스턴스를 만듭니다. 사용자 지정 정책은 스레드 우선 순위가 최고 우선 순위 클래스가 되도록 지정합니다.

이 예제에서는 Concurrency::callConcurrency::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

참고 항목

작업

방법: 특정 스케줄러 정책을 사용하는 에이전트 만들기

기타 리소스

스케줄러 정책

방법: 스케줄러 인스턴스 관리