Scheduler Instances
This document describes the role of scheduler instances in the Concurrency Runtime and how to use the concurrency::Scheduler and concurrency::CurrentScheduler classes to create and manage scheduler instances. Scheduler instances are useful when you want to associate explicit scheduling policies with specific types of workloads. For example, you can create one scheduler instance to run some tasks at an elevated thread priority and use the default scheduler to run other tasks at the normal thread priority.
Tip
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.
Sections
The Scheduler and CurrentScheduler Classes
The Task Scheduler enables applications to use one or more scheduler instances to schedule work. The concurrency::Scheduler class represents a scheduler instance and encapsulates the functionality that is related to scheduling tasks.
A thread that is attached to a scheduler is known as an execution context, or just context. One scheduler can be active on the current context at any time. The active scheduler is also known as the current scheduler. The Concurrency Runtime uses the concurrency::CurrentScheduler class to provide access to the current scheduler. The current scheduler for one context can differ from the current scheduler for another context. The runtime does not provide a process-level representation of the current scheduler.
Typically, the CurrentScheduler
class is used to access the current scheduler. The Scheduler
class is useful when you need to manage a scheduler that is not the current one.
The following sections describe how to create and manage a scheduler instance. For a complete example that illustrates these tasks, see How to: Manage a Scheduler Instance.
[Top]
Creating a Scheduler Instance
There are these three ways to create a Scheduler
object:
If no scheduler exists, the runtime creates a default scheduler for you when you use runtime functionality, for example, a parallel algorithm, to perform work. The default scheduler becomes the current scheduler for the context that initiates the parallel work.
The concurrency::CurrentScheduler::Create method creates a
Scheduler
object that uses a specific policy and associates that scheduler with the current context.The concurrency::Scheduler::Create method creates a
Scheduler
object that uses a specific policy, but does not associate it with the current context.
Allowing the runtime to create a default scheduler enables all concurrent tasks to share the same scheduler. Typically, the functionality that is provided by the Parallel Patterns Library (PPL) or the Asynchronous Agents Library is used to perform parallel work. Therefore, you do not have to work directly with the scheduler to control its policy or lifetime. When you use the PPL or the Agents Library, the runtime creates the default scheduler if it does not exist and makes it the current scheduler for each context. When you create a scheduler and set it as the current scheduler, then the runtime uses that scheduler to schedule tasks. Create additional scheduler instances only when you require a specific scheduling policy. For more information about the policies that are associated with a scheduler, see Scheduler Policies.
[Top]
Managing the Lifetime of a Scheduler Instance
The runtime uses a reference-counting mechanism to control the lifetime of Scheduler
objects.
When you use the CurrentScheduler::Create
method or the Scheduler::Create
method to create a Scheduler
object, the runtime sets the initial reference count of that scheduler to one. The runtime increments the reference count when you call the concurrency::Scheduler::Attach method. The Scheduler::Attach
method associates the Scheduler
object together with the current context. This makes it the current scheduler. When you call the CurrentScheduler::Create
method, the runtime both creates a Scheduler
object and attaches it to the current context (and sets the reference count to one). You can also use the concurrency::Scheduler::Reference method to increment the reference count of a Scheduler
object.
The runtime decrements the reference count when you call the concurrency::CurrentScheduler::Detach method to detach the current scheduler, or call the concurrency::Scheduler::Release method. When the reference count reaches zero, the runtime destroys the Scheduler
object after all scheduled tasks finish. A running task is allowed to increment the reference count of the current scheduler. Therefore, if the reference count reaches zero and a task increments the reference count, the runtime does not destroy the Scheduler
object until the reference count again reaches zero and all tasks finish.
The runtime maintains an internal stack of Scheduler
objects for each context. When you call the Scheduler::Attach
or CurrentScheduler::Create
method, the runtime pushes that Scheduler
object onto the stack for the current context. This makes it the current scheduler. When you call CurrentScheduler::Detach
, the runtime pops the current scheduler from the stack for current context and sets the previous one as the current scheduler.
The runtime provides several ways to manage the lifetime of a scheduler instance. The following table shows the appropriate method that releases or detaches the scheduler from the current context for each method that creates or attaches a scheduler to the current context.
Create or attach method | Release or detach method |
---|---|
CurrentScheduler::Create |
CurrentScheduler::Detach |
Scheduler::Create |
Scheduler::Release |
Scheduler::Attach |
CurrentScheduler::Detach |
Scheduler::Reference |
Scheduler::Release |
Calling the inappropriate release or detach method produces unspecified behavior in the runtime.
When you use functionality, for example, the PPL, that causes the runtime to create the default scheduler for you, do not release or detach this scheduler. The runtime manages the lifetime of any scheduler that it creates.
Because the runtime does not destroy a Scheduler
object before all tasks have finished, you can use the concurrency::Scheduler::RegisterShutdownEvent method or the concurrency::CurrentScheduler::RegisterShutdownEvent method to receive a notification when a Scheduler
object is destroyed. This is useful when you must wait for every task that is scheduled by a Scheduler
object to finish.
[Top]
Methods and Features
This section summarizes the important methods of the CurrentScheduler
and Scheduler
classes.
Think of the CurrentScheduler
class as a helper for creating a scheduler for use on the current context. The Scheduler
class lets you control a scheduler that belongs to another context.
The following table shows the important methods that are defined by the CurrentScheduler
class.
Method | Description |
---|---|
Create | Creates a Scheduler object that uses the specified policy and associates it with the current context. |
Get | Retrieves a pointer to the Scheduler object that is associated with the current context. This method does not increment the reference count of the Scheduler object. |
Detach | Detaches the current scheduler from the current context and sets the previous one as the current scheduler. |
RegisterShutdownEvent | Registers an event that the runtime sets when the current scheduler is destroyed. |
CreateScheduleGroup | Creates a concurrency::ScheduleGroup object in the current scheduler. |
ScheduleTask | Adds a lightweight task to the scheduling queue of the current scheduler. |
GetPolicy | Retrieves a copy of the policy that is associated with the current scheduler. |
The following table shows the important methods that are defined by the Scheduler
class.
Method | Description |
---|---|
Create | Creates a Scheduler object that uses the specified policy. |
Attach | Associates the Scheduler object together with the current context. |
Reference | Increments the reference counter of the Scheduler object. |
Release | Decrements the reference counter of the Scheduler object. |
RegisterShutdownEvent | Registers an event that the runtime sets when the Scheduler object is destroyed. |
CreateScheduleGroup | Creates a concurrency::ScheduleGroup object in the Scheduler object. |
ScheduleTask | Schedules a lightweight task from the Scheduler object. |
GetPolicy | Retrieves a copy of the policy that is associated with the Scheduler object. |
SetDefaultSchedulerPolicy | Sets the policy for the runtime to use when it creates the default scheduler. |
ResetDefaultSchedulerPolicy | Restores the default policy to the one that was active before the call to SetDefaultSchedulerPolicy . If the default scheduler is created after this call, the runtime uses default policy settings to create the scheduler. |
[Top]
Example
For basic examples of how to create and manage a scheduler instance, see How to: Manage a Scheduler Instance.
See also
Task Scheduler
How to: Manage a Scheduler Instance
Scheduler Policies
Schedule Groups
الملاحظات
https://aka.ms/ContentUserFeedback.
قريبًا: خلال عام 2024، سنتخلص تدريجيًا من GitHub Issues بوصفها آلية إرسال ملاحظات للمحتوى ونستبدلها بنظام ملاحظات جديد. لمزيد من المعلومات، راجعإرسال الملاحظات وعرضها المتعلقة بـ