· Система выделяет процессорное время всем активным потокам, исходя из их уровней приоритета, которые варьируются от 0 до 31.
Низший уровень является зарезервированным и назначается специальному системному потоку обнуления страниц.
Когда система подключает процессор к потоку, он обрабатывает потоки с одинаковым приоритетом как равноправные. Как только все потоки с данным приоритетом получат по кванту и при условии, что они больше не требуют процессорного времени ОС переходит к потокам с более низким приоритетом.
Существует вероятность, что процессор постоянно обрабатывает потоки, например с приоритетом 31. Значит у потоков с более низким приоритетом нет шансов на подключение к процессору. Такая ситуация называется перегрузкой(starvation - зависание). Но вероятность такой ситуации мала. В обычных условиях потоки зачастую просто простаивают.
Допустим, что исполняется поток с приоритетом 5. В это время потоку с более высоким приоритетом понадобился процессор. ОС немедленно остановит поток с низким приоритетом, даже если не истек отведенный ему квант времени, после чего подключит поток с более высоким приоритетом, выделив ему полный квант времени.
|
|
· Потоки с более высоким приоритетом всегда вытесняют потоки с более низким приоритетом, независимо от того, исполняются последние или нет.
Уровень приоритета присваивается в два этапа:
1. процессу присваивается определенный класс приоритета
2. потокам, принадлежащим процессу, присваиваются относительные уровни приоритета.
Классы приоритета процесса:
Класс | Флаг | Уровень |
простаивающий(idle) | IDLE_PRIORITY_CLASS | |
обычный(normal) | NORMAL_PRIORITY_CLASS | |
высокий(high) | HIGH_PRIORITY_CLASS | |
реального времени(realtime) | REALTIME_PRIORITY_CLASS |
Большинство приложений в основном относятся к приложениям с обычным классом приоритета. Такие процессы ведут себя несколько иначе:
· Windows NT увеличивает квант времени потокам активного процесса. Например: потоки обычного процесса получают 15 мс процессорного времени, до тех пор, пока не становятся активными. В этом состоянии им достается 45 мс (диалог Панель управления\Система\Perfomance позволяет регулировать во сколько раз необходимо увеличить квант).
· Windows 95 повышает уровень потока на 1 для активного процесса. Когда процесс уходит в "фон" уровень потока снижается на 1.
Причина таких изменений в активных процессах связана с тем, что система добивается быстрого реагирования на пользовательский ввод.
Приоритет idle идеален для приложений, занимающихся мониторингом системы (например, программы - экранные заставки).
Класс приоритета high следует использовать только в крайней необходимости (например: Explorer).
|
|
Приоритет realtime практически никогда не используется, кроме случаев работы с нестандартным оборудованием или когда программа выполняет быстротечную операцию, которую нельзя прерывать.
Узнать о приоритете процесса можно с помощью функции
function GetPriorityClass (hProcess: THandle): DWORD;
а установить
function SetPriorityClass (hProcess: THandle; dwPriorityClass: DWORD): BOOL;
Когда создается новый поток, уровень его приоритета соответствует классу процесса. Но существует возможность повысить или понизить уровень приоритета отдельного потока относительно процесса.
function SetThreadPriority (hThread:THandle;nPriority:Integer): BOOL;
nPriority может принимать следующие значения
Значение | Описание |
THREAD_PRIORITY_LOWEST | -2 единицы |
THREAD_PRIORITY_BELOW_NORMAL | -1 единица |
THREAD_PRIORITY_NORMAL | |
THREAD_PRIORITY_ABOVE_NORMAL | +1 единицы |
THREAD_PRIORITY_HIGHEST | +2 единицы |
Повторные вызовы SetThreadPriority не дают кумулятивного эффекта.
Следующая функция позволяет узнать относительный приоритет процесса
function GetThreadPriority (hThread: THandle): Integer;
Существует возможность задержать выполнение потока как при его создании (флаг CREATE_SUSPENDED) так и с помощью вызова функции function SuspendThread (hThread:THandle):DWORD, которая увеличивает счетчик простоев потока. При удачном выполнении функция возвращает предыдущее значение счетчика простоев или $FFFFFFFF. Чтобы возобновить выполнение потока необходимо из другого потока вызвать функцию function ResumeThread (hThread:THandle):DWORD, которая уменьшит счетчик простоев на единицу и если он будет равен 0, запустит поток на выполнение. Приостановить поток можно не более чем 127 раз.