Лекция 5 распределение процессорного времени между потоками

· Система выделяет процессорное время всем активным потокам, исходя из их уровней приоритета, которые варьируются от 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 раз.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: