Розподіл процесорного часу між потоками

Система виділяє процесорний час всім активним потокам, виходячи з їх рівнів пріоритету, які варіюються від 0 до 31.

Нижчий рівень є зарезервованим і призначається спеціальним системному потоку обнулення сторінок.

Коли система підключає процесор до потоку, він обробляє потоки з однаковим пріоритетом як рівноправні (за принципом каруселі). Як тільки все потоки з даними пріоритетом отримають по кванту і за умови, що вони більше не вимагають процесорного часу, ОС переходить до потокам з більш низьким пріоритетом.

Існує ймовірність, що процесор постійно обробляє потоки, наприклад з пріоритетом 31. Значить у потоків з більш низьким пріоритетом немає шансів на підключення до процесора. Така ситуація називається перевантаженням (starvation - зависання).

Створення потоку з відносним пріоритетом idle:

HANDLE hThread = CreateThread (NULL, 0, ThreadFunc, NULL, CREATE_SUSPENDED, dwThreadID); SetThreadPriority (hThread, THREAD_PRIORITY_IDLE); ResumeThread (hThread);

CreateThread завжди створює потік з відносним пріоритетом normal.

Щоб привласнити потоку відносний пріоритет idle, потрібно створити призупинений потік, передавши в CreateThread прапор CREATE_SUSPENDED, а потім викликати SetThreadPriority і встановити потрібний пріоритет.

Призупинення та відновлення потоків:

Призупинити виконання потоку можна також за допомогою виклику функції

DWORD SuspendThread (HANDLE hThread);

яка збільшує лічильник простоїв потоку. При вдалому виконанні функція повертає попереднє значення лічильника простоїв або $ FFFFFFFF.

Щоб відновити виконання потоку необхідно з іншого потоку викликати функцію

DWORD ResumeThread (HANDLE hThread);

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

Призупинити потік можна не більше ніж 127 разів.

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

Потік може повідомити системі не виділяти йому процесорний час на певний період, викликавши:

VOID Sleep (DWORD dwMilliseconds);

Ця функція призупиняє потік на dwMilliseconds мілісекунд.

Викликаючи Sleep, потік добровільно відмовляється від залишку виділеного йому кванта часу.

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

Можна викликати Sleep і передати в dwMilliseconds значення INFINITE, взагалі заборонивши планувати потік.

Можна викликати Sleep і передати в dwMilliseconds нульове значення. Тоді Ви відмовитеся від залишку свого кванта часу і змусите систему підключити до процесора інший потік.