Приоритеты потоков
Теперь рассмотрим уровни приоритета, которые могут быть присвоены потокам процесса. Внутри каждого процесса, которому присвоен какой-либо класс приоритета, могут существовать потоки, уровень приоритета которых принимает одно из семи возможных значений:
- 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.
Типичной стратегией является повышение уровня до…ABOVE_NORMAL или…HIGHEST для потоков, которые должны быстро реагировать на действия пользователя по вводу информации. Потоки, которые интенсивно используют процессор для вычислений, часто относят к фоновым. Им дают уровень приоритета…BELOW_NORMAL или…LOWEST, так чтобы при необходимости они могли быть вытеснены.
Иногда возникает ситуация, когда поток с более высоким приоритетом должен ждать поток с низким приоритетом, пока тот не закончит какую-либо операцию. В этом случае не следует программировать ожидание завершения операции в виде цикла, так как львиная доля времени процессора уйдет на выполнение команд этого цикла. Возможно даже зацикливание – ситуация типа deadlock, так как поток с более низким приоритетом не имеет шанса получить управление и завершить операцию. Обычной практикой в таких случаях является использование:
- одной из функций ожидания (wait functions);
- вызов функции Sleep (sleepEx);
- вызов функции SwitchToThread;
- использование объекта типа critical section (критическая секция), который мы рассмотрим позже.
Для определения текущего уровня приоритета потока существует функция GetThreadPriority, которая возвращает один из семи рассмотренных уровней. Базовый приоритет потока, как было упомянуто, является комбинацией класса приоритета процесса и уровня приоритета потока. Он вычисляется в соответствии с таблицей, которая довольно объемна (47 строк) и поэтому здесь не приводится. Просмотрите ее в справке (Help), в разделе Platform SDK-Scheduling Priorities (Платформа, SDK-Планирование приоритетов).
К примеру, первичный поток процесса с классом HIGH_PRIORITY_CLASS по умолчанию получает начальное значение уровня приоритета THREAD_PRIORITY_NORMAL. Эта комбинация образует базовый уровень приоритета, равный 13. Если впоследствии вы присвоите потоку с помощью функции SetThreadPriority уровень…ьоиЕЗТ, то эта комбинация задаст базовый уровень 11. Если же вы для потока выберете уровень…IDLE, то базовый уровень скакнет и опустится до единицы. Считая, что класс приоритета процесса не изменяется и остается равным HIGH_PRIORITY_CLASS, сведем все семь возможных вариантов в табл. 12.1.
Таблица 12.1. Приоритеты потоков.
Уровень приоритета потока | Базовый уровень |
---|---|
THREAD_PRIORITY_IDLE | 1 |
THREAD_PRIORITY_LOWEST | 11 |
THREAD_PRIORITY_8ELOW_NORMAL | 12 |
THREAD_PRIORITY_NORMAL | 13 |
THREAD_PRIORITY_ABOVE_NORMAL | 14 |
THREAD_PRIORITY_HIGHEST | 15 |
THREAD_PRIORITY_TIME_CRITICAL | 15 |