Пріоритети потоків - глава 29

Інтерфейс Win32 API дозволяє програмісту управляти розподілом часу між потоками; це поширюється і на додатки, написані на Delphi. Операційна система планує час процесора відповідно до пріоритетів потоків.

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

У свою чергу, процеси можуть мати такі класи пріоритетів.

  • Real time;
  • Normal;
  • High;
  • Below normal;
  • Above normal;
  • Idle.

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

Використання класу High обмежене процесами, які повинні завершуватися за короткий час, щоб не викликати збійної ситуації. Приклад - процес, який посилає сигнали зовнішнього пристрою; причому пристрій відключається, якщо не отримає своєчасний сигнал. Якщо у вас виникли проблеми з продуктивністю вашої програми, було б неправильно вирішувати їх просто за рахунок підвищення його пріоритету до high - такий процес також впливає на всю ОС. Можливо, в цьому випадку слід модернізувати комп'ютер.

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

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

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

І ще для класу Normal приведені по два пріоритети, забезпечені буквами В (Background) і F (Foreground). Пояснення цьому дається нижче.

Крім базового пріоритету, описуваного в цій таблиці, планувальник завдань (scheduler) може призначати так звані динамічні пріоритети. Для процесів класу NORMAL_PRIORITY_CLASS при перемиканні з фонового режиму в режим переднього плану і в ряді інших випадків пріоритет потоку, з яким створено вікно переднього плану, підвищується. Так працюють всі клієнтські операційні системи від Microsoft. Серверні операційні системи оптимізовані для виконання фонових додатків. Втім, Windows NT і більш пізні ОС на цьому ядрі дозволяють перемикати режим оптимізації, використовуючи перемикач Application response аплета System панелі управління Windows (рис. 29.1).

Мал. 29.1. За допомогою діалогу Performance Options можна управляти алгоритмом призначення пріоритетів

Тепер, розібравшись в пріоритетах потоків, потрібно обов'язково сказати про те, як же їх використовує планувальник завдань для розподілу процесорного часу.

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

  • виконується потік зупинився для очікування;
  • з'явився готовий до виконання потік з вищим пріоритетом.

Тепер, напевно, вам більше зрозуміла небезпека, що виходить від невиправданого завищення пріоритетів. Адже, якщо є активні потоки з високим пріоритетом, жоден потік з більш низьким пріоритетом жодного разу не отримає часу процесора. Ця проблема може підстерігати вас навіть на рівні вашого застосування. Припустимо, ви призначили обчислювальному потоку пріоритет THREAD_PRIORITY_ABOVE_NORMAL, а потоку, де обробляється введення користувача, - THREAD_PRIORITY_BELOW_NORMAL. Тоді замість запланованого результату - поєднати обчислення з нормальною реакцією додатки - ви отримаєте строго зворотний. Додаток взагалі перестане відгукуватися на введення, і зняти його буде можливо тільки за допомогою засобів ОС.

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


Схожі статті