This document describes the role of scheduler policies in the Concurrency Runtime. A scheduler policy controls the strategy that the scheduler uses when it manages tasks. For example, consider an application that requires for some tasks to use user-mode schedulable (UMS) threads and other tasks to use the normal threading mechanism. You can create two scheduler instances: one that specifies the creation of UMS threads as part of its scheduler policy and another that specifies normal threads as part of its scheduler policy. For more information about UMS, see User-Mode Scheduling.
Scheduler policies also let you divide the available processing resources and assign a fixed set of resources to each scheduler. For example, consider a parallel algorithm that does not scale beyond four processors. You can create a scheduler policy that limits its tasks to use no more than four processors concurrently.
The Concurrency Runtime provides a default scheduler, and therefore you are not required to create one in your application. Because the Task Scheduler helps you fine-tune the performance of your applications, we recommend that you start with the Parallel Patterns Library (PPL) or the Asynchronous Agents Library if you are new to the Concurrency Runtime.
When you use the Concurrency::CurrentScheduler::Create, Concurrency::Scheduler::Create, or Concurrency::Scheduler::SetDefaultSchedulerPolicy method to create a scheduler instance, you provide a Concurrency::SchedulerPolicy object that contains a collection of key-value pairs that specify the behavior of the scheduler. The SchedulerPolicy constructor takes a variable number of arguments. The first argument is the number of policy elements that you are about to specify. The remaining arguments are key-value pairs for each policy element. The following example creates a SchedulerPolicy object that specifies three policy elements. The runtime uses the default values for the policy keys that are not specified.
The Concurrency::PolicyElementKey enumeration defines the policy keys that are associated with the Task Scheduler. The following table describes the policy keys and the default value that the runtime uses for each of them.
A Concurrency::SchedulerType value that specifies whether to use normal threads or UMS threads to schedule tasks.
ThreadScheduler (use normal threads)
An unsigned int value that specifies the maximum number of concurrency resources that the scheduler uses.
An unsigned int value that specifies the minimum number of concurrency resources that the scheduler uses.
An unsigned int value that specifies how many threads to allocate to each processing resource.
An unsigned int value that specifies the maximum number of contexts that can be cached in the local queue of each virtual processor.
An unsigned int value that specifies the size of the stack, in kilobytes, to reserve for each context.
0 (use the default stack size)
An int value that specifies the thread priority of each context. This can be any value that you can pass to SetThreadPriority or INHERIT_THREAD_PRIORITY.
A Concurrency::SchedulingProtocolType value that specifies the scheduling algorithm to use.
A Concurrency::DynamicProgressFeedbackType value that specifies whether to rebalance resources according to statistics-based progress information.
Note Do not set this policy to ProgressFeedbackDisabled. ProgressFeedbackDisabled is reserved for use by the runtime.
Each scheduler uses its own policy when it schedules tasks. Therefore, the policies that are associated with one scheduler do not affect the behavior of any other scheduler. In addition, you cannot change the scheduler policy after you create the Scheduler object.
Use only scheduler policies to control the attributes for threads that the runtime creates. Changing the thread affinity or priority of threads that are created by the runtime produces undefined behavior.
The runtime creates a default scheduler for you if you do not explicitly create one. If you want to use the default scheduler in your application, but you want to specify a policy for that scheduler to use, call the Concurrency::Scheduler::SetDefaultSchedulerPolicy method before you schedule parallel work. If you do not call the Scheduler::SetDefaultSchedulerPolicy method, the runtime uses the default policy values from the table.
Use the Concurrency::CurrentScheduler::GetPolicy and the Concurrency::Scheduler::GetPolicy methods to retrieve a copy of the scheduler policy. The policy values that you receive from these methods can differ from the policy values that you specify when you create the scheduler. For example, the UMSThreadDefault policy value specifies that the scheduler uses UMS threads if that feature is available on the operating system (for example, the 64-bit version of Windows 7). If UMS threads are not available, the scheduler sets this policy value to ThreadScheduler, which specifies that the scheduler is to use normal threads.
For examples that use specific scheduler policies to control the behavior of the scheduler, see How to: Specify Specific Scheduler Policies and How to: Create Agents that Use Specific Scheduler Policies.