Scheduling
The Windows operating system provides a robust scheduling mechanism to manage the execution of processes and threads. This section details the APIs related to process and thread scheduling, allowing developers to influence and monitor execution priorities, affinities, and timing.
Process Priority
Processes have a base priority level that influences how they are treated by the scheduler. You can adjust this priority to give a process more or less CPU time. Higher priority processes are generally given preference over lower priority processes.
HANDLE OpenProcess(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwProcessId
);
BOOL SetPriorityClass(
HANDLE hProcess,
DWORD dwPriorityClass
);
Common priority classes include:
IDLE_PRIORITY_CLASS
BELOW_NORMAL_PRIORITY_CLASS
NORMAL_PRIORITY_CLASS
ABOVE_NORMAL_PRIORITY_CLASS
HIGH_PRIORITY_CLASS
REALTIME_PRIORITY_CLASS
For more details, see Priority Class Details.
Thread Priority
Individual threads within a process can also have their priorities adjusted. Thread priority is relative to the process's priority class. Setting a thread's priority can significantly impact its responsiveness and resource consumption.
BOOL SetThreadPriority(
HANDLE hThread,
int nPriority
);
int GetThreadPriority(
HANDLE hThread
);
Thread priorities range from THREAD_PRIORITY_LOWEST
(-2) to THREAD_PRIORITY_HIGHEST
(2), with THREAD_PRIORITY_NORMAL
(0) as the default.
For more details, see Thread Priority Levels.
CPU Affinity
CPU affinity allows you to specify which processor(s) a thread or process can run on. This is useful for performance tuning, especially on multi-core systems, or for debugging specific processor-related issues.
DWORD_PTR SetProcessAffinityMask(
HANDLE hProcess,
DWORD_PTR dwProcessAffinityMask
);
DWORD_PTR GetProcessAffinityMask(
HANDLE hProcess,
LPDWORD pdwProcessAffinityMask,
LPDWORD pdwSystemAffinityMask
);
The affinity mask is a bitmask where each bit corresponds to a logical processor. For example, a mask of 0x00000001
would bind the thread/process to the first processor (CPU 0).
Job Objects
Job objects provide a mechanism for managing groups of processes. You can use job objects to set limits on resources that all processes within the job can consume, including CPU time, memory, and I/O operations. They offer advanced control over process execution and lifecycle.
HANDLE CreateJobObjectA(
LPSECURITY_ATTRIBUTES lpJobAttributes,
LPCSTR lpName
);
BOOL AssignProcessToJobObject(
HANDLE hJob,
HANDLE hProcess
);
Key functionalities include:
- Setting overall CPU usage limits.
- Enforcing memory limits.
- Specifying I/O limits.
- Controlling process creation within the job.
Priority Class Details
The priority class of a process is a fundamental property that the Windows scheduler uses to determine how often a process gets to run. Each priority class has an associated base priority level for the threads within that process.
Priority Class | Description | Base Priority Range |
---|---|---|
IDLE_PRIORITY_CLASS |
Processes with this priority class run only when the system is idle. They are preempted by all other threads. | 0-1 |
BELOW_NORMAL_PRIORITY_CLASS |
Processes with this priority class have a slightly lower priority than normal. | 4-6 |
NORMAL_PRIORITY_CLASS |
Processes with this priority class have a normal priority. This is the default for most applications. | 7-9 |
ABOVE_NORMAL_PRIORITY_CLASS |
Processes with this priority class have a slightly higher priority than normal. | 10-12 |
HIGH_PRIORITY_CLASS |
Processes with this priority class have a high priority. They are scheduled before normal priority threads. | 13-15 |
REALTIME_PRIORITY_CLASS |
Processes with this priority class have the highest priority. They can starve other processes if not managed carefully. Use with extreme caution. | 24-31 |
Thread Priority Levels
Threads have priorities that are relative to their process's priority class. The scheduler dynamically adjusts thread priorities based on factors like user interaction and I/O completion. However, explicit setting allows for fine-grained control.
Constant | Value | Description |
---|---|---|
THREAD_PRIORITY_LOWEST |
-2 | The lowest priority. |
THREAD_PRIORITY_BELOW_NORMAL |
-1 | Below normal priority. |
THREAD_PRIORITY_NORMAL |
0 | Normal priority. This is the default. |
THREAD_PRIORITY_ABOVE_NORMAL |
1 | Above normal priority. |
THREAD_PRIORITY_HIGHEST |
2 | The highest priority. |
THREAD_PRIORITY_IDLE |
-15 | Idle priority. The thread only runs when no other thread is ready to run. |
Note: The actual priority level a thread runs at is a combination of its base priority and dynamic adjustments made by the scheduler.