Планувальник Windows

Завданням планувальника є вибір чергової нитки для виконання. Планувальник викликається в трьох випадках:

· Якщо закінчується квант часу, виділений поточної нитки;

· Якщо поточна нитка викликала блокуючу функцію (наприклад, WaitForMultipleObjects або ReadFile) і перейшла в стан очікування;

· Якщо нитка з більш високим пріоритетом прокинулася від очікування або була тільки що запущена.

Для вибору нитки використовується алгоритм пріоритетною черзі. Для кожного рівня пріоритету система веде чергу активних ниток (тобто ниток, що знаходяться в стані готовності). Для виконання вибирається чергова нитка з непорожній черзі з найвищим пріоритетом.

Черги активних ниток поповнюються за рахунок ниток, проснувшихся після стану очікування і ниток, витіснених планувальником. Як правило, нитка поміщається в кінець черги. Виняток робиться для нитки, витісненої до закінчення її кванта часу більш пріоритетною ниткою. Така «скривджена» нитка ставиться в голову черги.

Значення кванта часу для серверних установок Windows одно зазвичай 120 мс, для робочих станцій - 20 мс.

Як ви думаєте, чому для серверів квант часу більше?

Тепер докладніше про пріоритети. Хоча загальна схема їх призначення однакова для всіх версій Windows, деталі можуть різнитися. Подальший виклад орієнтований на Windows NT 4.0.

Всі рівні пріоритету ниток пронумеровані від 0 (найнижчий пріоритет) до 31 (найвищий). Рівні від 16 до 31 називаються пріоритетами реального часу, вони призначені для виконання критичних за часом системних операцій. Тільки сама система або користувач з правами адміністратора можуть використовувати пріоритети з цієї групи. Рівні від 0 до 15 називаються динамічними пріоритетами.

У Windows використовується двоступенева схема призначення пріоритетів. При створенні процесу йому призначається (а згодом може бути змінений самою програмою або користувачем) один з чотирьох класів пріоритету, з кожним з яких пов'язано базове значення пріоритету:

· Realtime (базовий пріоритет 24) - вищий клас пріоритету, допустимий тільки для системних процесів, що займають процесор на дуже короткий час;

· High (базовий пріоритет 13) - клас високопріоритетних процесів;

· Normal (базовий пріоритет 8) - звичайний клас пріоритету, до якого відноситься велика частина запускаються прикладних процесів;

· Idle (базовий пріоритет 4) - нижчий (буквально - «холостий» або «простоює») клас пріоритету, характерний для екранних заставок, моніторів продуктивності та інших програм, які не повинні заважати жити більш важливим програмам.

Власне пріоритет пов'язується не з процесом, а з кожною його ниткою. Пріоритет нитки визначається базовим пріоритетом процесу, до якого додається відносний пріоритет нитки - величина від -2 до +2. Відносний пріоритет призначається нитки при її створенні і може при необхідності змінюватися. Є також можливість призначити нитки критичний пріоритет (31 для процесів реального часу, 15 для інших) або холостий пріоритет (16 для процесів реального часу, 0 для решти).

Для ниток процесів реального часу пріоритети є статичними в тому сенсі, що система не намагається їх змінювати на свій розсуд. Передбачається, що для цієї групи процесів співвідношення пріоритетів має бути саме таким, як задумав програміст.

Для процесів трьох нижчих класів їх пріоритети не випадково називаються динамічними. Планувальник може змінювати пріоритети, а заодно і кванти часу для ниток в ході їх виконання, щоб досягти більш справедливого розподілу процесорного часу. Правила зміни динамічних пріоритетів наступні.

· Коли заблокована нитка дочекалася потрібного їй події, до пріоритету нитки додається величина, що залежить від причини очікування. Ця надбавка може досягати 6 одиниць (але пріоритет не повинен перевищити 15), якщо нитка розблокована внаслідок натискання клавіші або кнопки миші. Таким способом система прагне зменшити час реакції на дії користувача. Всякий раз, коли нитка повністю використовує свій квант часу, надбавка зменшується на 1, поки пріоритет нитки не повернеться до свого заданому значенню.

· Якщо нитка володіє вікном переднього плану (тобто тим, з яким працює користувач), то заради зменшення часу реакції планувальник може збільшити квант часу для цієї нитки з 20 мс до 40 або 60 мс, в залежності від налаштувань системи.

· Якщо планувальник виявляє, що деяка нитка перебуває в черзі більше 3 с, то він підвищує її пріоритет аж до 15 і подвоює її квант. Але ця благодійність разова: коли Попелюшка-нить витратить збільшений квант або заблокується, її пріоритет і квант повертаються до колишніх значень. Сенс акції зрозумілий: система намагається забезпечити хоч якесь просування навіть для низькопріоритетних ниток.