Система выделяет процессорное время всем активным потокам, исходя из их уровней приоритета, которые варьируются от 0 до 31.
Низший уровень является зарезервированным и назначается специальному системному потоку обнуления страниц.
Когда система подключает процессор к потоку, он обрабатывает потоки с одинаковым приоритетом как равноправные (по принципу карусели). Как только все потоки с данным приоритетом получат по кванту и при условии, что они больше не требуют процессорного времени, ОС переходит к потокам с более низким приоритетом.
Существует вероятность, что процессор постоянно обрабатывает потоки, например с приоритетом 31. Значит у потоков с более низким приоритетом нет шансов на подключение к процессору. Такая ситуация называется перегрузкой (starvation – зависание).
Допустим, что исполняется поток с приоритетом 5. В это время потоку с более высоким приоритетом понадобился процессор. ОС немедленно остановит поток с низким приоритетом, даже если не истек отведенный ему квант времени, после чего подключит поток с более высоким приоритетом, выделив ему полный квант времени.
Чтобы все потоки работали, ОС выделяет каждому из них определенные отрезки времени, которые называются квантами. Время выделяется по принципу «карусели».
Принцип вытесняющей многозадачности:
Потоки с более высоким приоритетом всегда вытесняют потоки с более низким приоритетом, независимо от того, исполняются последние или нет.
Уровень приоритета присваивается в два этапа (т.н. относительные приоритеты):
1. процессу присваивается определенный класс приоритета;
2. потокам, принадлежащим процессу, присваиваются относительные уровни приоритета
Классы приоритета потока:
Класс приоритета |
Уровень |
Описание |
Real-lime |
24 |
Потоки в этом процессе обязаны немедленно реагировать на события, обеспечивая выполнение критических по времени задач. Такие потоки вытесняют даже компоненты операционной системы. |
High |
13 |
Потоки в этом процессе тоже должны немедленно реагировать на события, обеспечивая выполнение критических по времени задач. Этот класс присвоен, например, Task Manager. |
Above Normal |
10 |
Класс приоритета, промежуточный между normal и high. Введен с Windows 2000. |
Normal |
8 |
Потоки в этом процессе не предъявляют особых требований к выделению им процессорного времени. |
Below Normal |
6 |
Класс приоритета, промежуточный между normal и idle. Введен с Windows 2000. |
Idle |
4 |
Потоки в этом процессе выполняются, когда система не занята другой работой. |
Большинство приложений в основном относятся к приложениям с обычным классом приоритета.
Такие процессы ведут себя несколько иначе:
Windows NT увеличивает квант времени потокам активного процесса. Например: потоки обычного процесса получают 15 мс процессорного времени, до тех пор, пока не становятся активными. В этом состоянии им достается 45 мс (диалог Панель управления \Система \Perfomance позволяет регулировать, во сколько раз необходимо увеличить квант).
Windows 95 повышает уровень потока на 1 для активного процесса. Когда процесс уходит в "фон", уровень потока снижается на 1.
Причина таких изменений в активных процессах связана с тем, что система добивается быстрого реагирования на пользовательский ввод.
Приоритет Idle идеален для приложений, занимающихся мониторингом системы (например, программы - экранные заставки).
Класс приоритета High следует использовать только в крайней необходимости (например: Explorer).
Приоритет Realtime практически никогда не используется, кроме случаев работы с нестандартным оборудованием или когда программа выполняет быстротечную операцию, которую нельзя прерывать.
Узнать о приоритете процесса можно с помощью функции
DWORD WINAPI GetPriorityClass(HANDLE hProcess);
а установить
BOOL WINAPI SetPriorityClass(HANDLE hProcess, DWORD dwPriorityClass);
Приоритет потока:
Когда создается новый поток, уровень его приоритета соответствует классу процесса.
Cуществует возможность повысить или понизить уровень приоритета отдельного потока относительно процесса.
BOOL SetThreadPriority( HANDLE hThread, int nPriority);
Относительный приоритет потока |
Идентификатор |
Описание |
Time-critical |
THREAD_PRIORITY_TIME_CRITICAL |
15 (31) |
Highest |
THREAD_PRIORITY_HIGHEST |
+2 |
Above normal |
THREAD_PRIORITY_ABOVE_NORMAL |
+1 |
Normal |
THREAD_PRIORITY_NORMAL |
0 |
Below normal |
THREAD_PRIORITY_BELOW_NORMAL |
-1 |
Lowest |
THREAD_PRIORITY_LOWEST |
-2 |
Idle |
THREAD_PRIORITY_IDLE |
1 (16) |
Только что созданный поток получает относительный приоритет Normal.
Повторные вызовы SetThreadPriority не дают кумулятивного эффекта
Следующая функция позволяет узнать относительный приоритет процесса:
int GetThreadPriority(HANDLE hThread);