Робота з "потоками" в середовищі Delphi

Информация - Компьютеры, программирование

Другие материалы по предмету Компьютеры, программирование

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

Тут ми розглянемо можливість для організації фонових дій (job) усередині однопотокової програми із збереженням реакції цього потоку на події від миші і клавіатури.

Ще не так давно програмісти намагалися емулювати потоки, запускаючи процедури усередині циклу обробки повідомлень Windows. Цикл обробки повідомлень (або цикл очікування) це особливий фрагмент коду в програмі, керованій подіями. Він виконується тоді, коли програма знаходить в черзі події, які потрібно обробити; якщо таких немає, програма може виконати в цей час фонову процедуру. Такий спосіб імітації потоків вельми складний, оскільки вимушує програміста, по-перше, зберігати стан фонової процедури між її викликами, а по-друге, визначати момент, коли вона поверне управління обробнику подій. Якщо така процедура виконується довго, то у користувача може скластися враження, що додаток перестав реагувати на зовнішні події. Використовування потоків знімає проблему перемикання контексту, тепер контекст (стек і регістри) зберігає операційна система.

У Delphi можливість створити фонову процедуру реалізована через подію Onldle.объекта Application!

type TIdleEvent = procedure (Sender: TObject;

var Done: Boolean)

of object;

property Onldle: TIdleEvent;

Обробник цієї події ви можете написати, помістивши на форму компонент TApplicationEvents із сторінки Additional Палітри компонентів.

Щоб зробити у фоновому режимі якусь роботу, слід розбити її на кванти і виконувати по одному кванту кожен виклик Onldle інакше додаток погано реагуватиме на зовнішні дії.

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

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

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

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

Примітка

Класи Above normal і Below normal зявилися вперше в Windows 2000.

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

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

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

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

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

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

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

 

Таблиця 29.1. Класи процесів і пріоритети їх потоків (для Windows 2000 і ХР)

IDLE_ PRIORITY CLASSBELOW_ NORMAL PRIORITY CLASSNORMAL_ PRIORITY_ CLASSABOVE_ NORMAL_ PRIORITY_ CLASSHIGH PRIORITY CLASSREALTIME PRIORITY CLASSTHREAD_ PRIORITY_

IDLE1111116THREAD_ PRIORITY LOWEST245 (B)

7 (F)81122THREAD_ PRIORITY_ BELOW NORMAL356 (B)

8 (F)91223THREAD_ PRIORITY_ NORMAL467 (B)

9 (F)101324THREAD PRIORITY_ ABOVE_ NORMAL578 (В)

10 (F)111425THREAD_ PRIORITY_ HIGHEST689 (B)

11 (F)121526THREAD_ PRIORITY TIME CRITICAL151515151531

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