Планирование приоритетов
Потоки запланированы на выполнение на основе их приоритета планирования. Каждому потоку назначается приоритет планирования. Уровни приоритета варьируются от нуля (наименьшего приоритета) до 31 (наивысший приоритет). Только поток нулевой страницы может иметь нулевой приоритет. (Поток нулевой страницы — это системный поток, отвечающий за ноль всех свободных страниц, если нет других потоков, которые необходимо запустить.)
Система обрабатывает все потоки с одинаковым приоритетом. Система назначает срезы времени циклическим перебором всем потокам с наивысшим приоритетом. Если ни один из этих потоков не готов к запуску, система назначает срезы времени циклическим перебором всем потокам с следующим наивысшим приоритетом. Если поток с более высоким приоритетом становится доступным для запуска, система перестает выполнять поток с более низким приоритетом (не позволяя ему завершить работу с срезом времени) и назначает полный рабочий день потоку с более высоким приоритетом. Дополнительные сведения см. в разделе "Параметры контекста".
Приоритет каждого потока определяется следующими критериями:
- Класс приоритета процесса
- Уровень приоритета потока в классе приоритета процесса
Класс приоритета и уровень приоритета объединяются для формирования базового приоритета потока. Сведения о динамическом приоритете потока см. в разделе Priority Boosts.
Класс Priority
Каждый процесс принадлежит одному из следующих классов приоритета:
- IDLE_PRIORITY_CLASS
BELOW_NORMAL_PRIORITY_CLASS
NORMAL_PRIORITY_CLASS
ABOVE_NORMAL_PRIORITY_CLASS
HIGH_PRIORITY_CLASS
REALTIME_PRIORITY_CLASS
По умолчанию класс приоритета процесса NORMAL_PRIORITY_CLASS. Используйте функцию CreateProcess , чтобы указать класс приоритета дочернего процесса при его создании. Если вызывающий процесс IDLE_PRIORITY_CLASS или BELOW_NORMAL_PRIORITY_CLASS, новый процесс наследует этот класс. Используйте функцию GetPriorityClass , чтобы определить текущий класс приоритета процесса и функцию SetPriorityClass , чтобы изменить класс приоритета процесса.
Процессы, отслеживающие систему, такие как экранные заставки или приложения, которые периодически обновляют дисплей, должны использовать IDLE_PRIORITY_CLASS. Это предотвращает мешает потокам этого процесса, которые не имеют высокого приоритета, вмешиваться в потоки с более высоким приоритетом.
Используйте HIGH_PRIORITY_CLASS с осторожностью. Если поток выполняется на самом высоком уровне приоритета в течение длительных периодов, другие потоки в системе не будут получать время процессора. Если одновременно задано несколько потоков с высоким приоритетом, потоки теряют свою эффективность. Высокоприоритетный класс должен быть зарезервирован для потоков, которые должны реагировать на критически важные события времени. Если приложение выполняет одну задачу, требующую высокоприоритетного класса, а остальные задачи являются обычным приоритетом, используйте SetPriorityClass , чтобы временно повысить класс приоритета приложения; затем уменьшите его после завершения критически важной задачи. Другая стратегия заключается в создании процесса с высоким приоритетом, который содержит все его потоки, блокировавшие большую часть времени, пробуждение потоков только в том случае, если требуются критические задачи. Важно отметить, что высокоприоритетный поток должен выполняться в течение короткого времени и только в том случае, если для выполнения критически важных операций требуется время.
Почти никогда не следует использовать REALTIME_PRIORITY_CLASS, так как это прерывает системные потоки, которые управляют вводом мыши, вводом клавиатуры и очисткой фонового диска. Этот класс может быть подходящим для приложений, которые "разговаривают" непосредственно с оборудованием или выполняют краткие задачи, которые должны иметь ограниченные перерывы.
Уровень приоритета
Ниже приведены уровни приоритета в каждом классе приоритета.
- THREAD_PRIORITY_IDLE
THREAD_PRIORITY_LOWEST
THREAD_PRIORITY_BELOW_NORMAL
THREAD_PRIORITY_NORMAL
THREAD_PRIORITY_ABOVE_NORMAL
THREAD_PRIORITY_HIGHEST
THREAD_PRIORITY_TIME_CRITICAL
Все потоки создаются с помощью THREAD_PRIORITY_NORMAL. Это означает, что приоритет потока совпадает с классом приоритета процесса. После создания потока используйте функцию SetThreadPriority , чтобы настроить приоритет относительно других потоков в процессе.
Типичная стратегия — использовать THREAD_PRIORITY_ABOVE_NORMAL или THREAD_PRIORITY_HIGHEST для входного потока процесса, чтобы обеспечить реагирование приложения на пользователя. Фоновые потоки, особенно те, которые являются ресурсоемкими для процессора, можно задать для THREAD_PRIORITY_BELOW_NORMAL или THREAD_PRIORITY_LOWEST, чтобы убедиться, что они могут быть упрещены при необходимости. Однако если у вас есть поток, ожидающий другого потока с более низким приоритетом для выполнения некоторых задач, обязательно заблокируйте выполнение ожидающего потока с высоким приоритетом. Для этого используйте функцию ожидания, критически важный раздел или функцию Спящего режима, SleepEx или SwitchToThread . Это предпочтительнее, чем выполнение цикла потока. В противном случае процесс может стать взаимоблокировкой, так как поток с более низким приоритетом никогда не планируется.
Чтобы определить текущий уровень приоритета потока, используйте функцию GetThreadPriority .
Базовый приоритет
Класс приоритета процесса и уровень приоритета потока объединяются для формирования базового приоритета каждого потока.
В следующей таблице показан базовый приоритет для сочетаний класса приоритета процесса и значения приоритета потока.
Класс приоритета процесса | Уровень приоритета потока | Базовый приоритет | |
---|---|---|---|
IDLE_PRIORITY_CLASS | THREAD_PRIORITY_IDLE | 1 | |
THREAD_PRIORITY_LOWEST | 2 | ||
THREAD_PRIORITY_BELOW_NORMAL | 3 | ||
THREAD_PRIORITY_NORMAL | 4 | ||
THREAD_PRIORITY_ABOVE_NORMAL | 5 | ||
THREAD_PRIORITY_HIGHEST | 6 | ||
THREAD_PRIORITY_TIME_CRITICAL | 15 | ||
BELOW_NORMAL_PRIORITY_CLASS | THREAD_PRIORITY_IDLE | 1 | |
THREAD_PRIORITY_LOWEST | 4 | ||
THREAD_PRIORITY_BELOW_NORMAL | 5 | ||
THREAD_PRIORITY_NORMAL | 6 | ||
THREAD_PRIORITY_ABOVE_NORMAL | 7 | ||
THREAD_PRIORITY_HIGHEST | 8 | ||
THREAD_PRIORITY_TIME_CRITICAL | 15 | ||
NORMAL_PRIORITY_CLASS | THREAD_PRIORITY_IDLE | 1 | |
THREAD_PRIORITY_LOWEST | 6 | ||
THREAD_PRIORITY_BELOW_NORMAL | 7 | ||
THREAD_PRIORITY_NORMAL | 8 | ||
THREAD_PRIORITY_ABOVE_NORMAL | 9 | ||
THREAD_PRIORITY_HIGHEST | 10 | ||
THREAD_PRIORITY_TIME_CRITICAL | 15 | ||
ABOVE_NORMAL_PRIORITY_CLASS | THREAD_PRIORITY_IDLE | 1 | |
THREAD_PRIORITY_LOWEST | 8 | ||
THREAD_PRIORITY_BELOW_NORMAL | 9 | ||
THREAD_PRIORITY_NORMAL | 10 | ||
THREAD_PRIORITY_ABOVE_NORMAL | 11 | ||
THREAD_PRIORITY_HIGHEST | 12 | ||
THREAD_PRIORITY_TIME_CRITICAL | 15 | ||
HIGH_PRIORITY_CLASS | THREAD_PRIORITY_IDLE | 1 | |
THREAD_PRIORITY_LOWEST | 11 | ||
THREAD_PRIORITY_BELOW_NORMAL | 12 | ||
THREAD_PRIORITY_NORMAL | 13 | ||
THREAD_PRIORITY_ABOVE_NORMAL | 14 | ||
THREAD_PRIORITY_HIGHEST | 15 | ||
THREAD_PRIORITY_TIME_CRITICAL | 15 | ||
REALTIME_PRIORITY_CLASS | THREAD_PRIORITY_IDLE | 16 | |
THREAD_PRIORITY_LOWEST | 22 | ||
THREAD_PRIORITY_BELOW_NORMAL | 23 | ||
THREAD_PRIORITY_NORMAL | 24 | ||
THREAD_PRIORITY_ABOVE_NORMAL | 25 | ||
THREAD_PRIORITY_HIGHEST | 26 | ||
THREAD_PRIORITY_TIME_CRITICAL | 31 |