Смекни!
smekni.com

Робота з "потоками" в середовищі Delphi (стр. 1 из 4)

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


Працюючи з Delphi, потрібно мати на увазі: цей чудовий продукт не тільки спрощує розробку складних додатків, він використовує при цьому всі можливості операційної системи. Одна з можливостей, яку підтримує Delphi, – це так звані потоки (threads) або нитки.

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

Операційна система (ОС) надає додатку деякий інтервал часу центрального процесора (ЦП) і в мить, коли додаток переходить до очікування повідомлень або звільняє процесор, операційна система передає управління іншій задачі. Тепер, коли комп'ютери з більш ніж одним процесором різко впали в ціні, а операційна система Windows NT може використовувати наявність декількох процесорів, користувачі дійсно можуть запускати одночасно більше однієї задачі. Плануючи час центрального процесора, Windows 95 або Windows NT розподіляють його між потоками, а не між додатками. Щоб використовувати всі переваги, забезпечувані декількома процесорами в сучасних операційних системах, програміст повинен знати, як створювати потоки.

У цьому рефераті розглядаються наступні питання:

· що таке потоки;

· різниця між потоком і процесом;

· переваги потоків;

· клас TThread в Delphi;

· реалізація багатопотокового додатку;

· синхронізація потоків.

Визначення потоку досить просте: потоки – це об'єкти, одержуючі час процесора. Час процесора виділяється квантами (quantum, time slice). Квант часу – це інтервал, що є у розпорядженні потоку доти. поки час не буде передано в розпорядження іншого потоку.

Кванти виділяються не програмам або процесам, а породженим ними потокам. Як мінімум, кожен процес має хоча б один (головний) потік, але сучасні операційні системи, починаючи з Windows 95 (для прихильників Borland Kylix і Linux також), дозволяють запустити в рамках процесу декілька потоків.

Найпростіший приклад їх використовування – додатки з складу Microsoft Office. Наприклад, пакети Excel і Word задіють по декілька потоків. Word може одночасно коректувати граматику і друкувати, при цьому здійснюючи введення даних з клавіатури і миші; програма Excel здатна виконувати фонові обчислення і друкувати.

Примітка

Взнати число потоків, запущених додатком, в Windows NT, 2000 і ХР можна за допомогою утиліти Task Manager (Диспетчер задач). Для цього серед показників, що відображаються у вікні Processes, потрібно вибрати опцію Thread Count. Так, у момент написання цих рядків MS Word використовував 5 потоків, середовище Delphi – 3.

Якщо задачі додатку можна розділити на різні підмножини: обробка подій, введення / висновок, зв'язок і ін., то потоки можуть бути органічно вбудовані в програмне рішення. Якщо розробник може розділити велику задачу на декілька дрібних, це тільки підвищить переносимість коду і можливості його багатократного використовування.

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

Інша важлива перевага упровадження потоків – при зростанні «навантаження» на додаток можна збільшити кількість потоків і тим самим зняти проблему.

Потоки спрощують життя тим програмістам, які розробляють додатки в архітектурі клієнт/сервер. Коли потрібне обслуговування нового клієнта, сервер може запустити спеціально для цього окремий потік. Такі потоки прийнято називати симетричними потоками (symmetric threads) – вони мають однакове призначення, виконують один і той же код і можуть розділяти одні і ті ж ресурси. Більш того, додатки, розраховані на серйозне навантаження, можуть підтримувати пул (pool) однотипних потоків. Оскільки створення потоку вимагає певного часу, для прискорення роботи бажано наперед мати потрібне число готових потоків і активізувати їх у міру підключення чергового клієнта.

Примітка

Такий підхід особливо характерний для Web‑серверу Microsoft Internet Information Services і додатків, оброблювальних запити в його середовищі. Якщо ви створюєте додатки ISAPI на Delphi, то можете використовувати пулінг потоків, підключивши до проекту модуль ISAPIThreadPool.pas. Якщо ви хочете запозичити ідеї для інших цілей, ознайомтеся з вмістом цього модуля.

Асиметричні потоки (asymmetric threads) – це потоки, вирішальні різні задачі і, як правило, не розділяючі сумісні ресурси. Необхідність в асиметричних потоках виникає:

· коли в програмі необхідні тривалі обчислення, при цьому необхідно зберегти нормальну реакцію на введення;

· коли потрібно обробляти асинхронне введення / висновок з використанням різних пристроїв (Сом-порту, звукової карти, принтера і т. п.);

· коли ви хочете створити декілька вікон і одночасно обробляти введення в них.

Коли ми говоримо «програма» (application), то звичайно маємо на увазі поняття, в термінології операційної системи що позначається як «процес». Процес складається з віртуальної пам'яті, виконуваного коду, потоків і даних. Процес може містити багато потоків, але обов'язково містить, принаймні, один. Потік, як правило, має «у власності» мінімум ресурсів; він залежить від процесу, який і розпоряджається віртуальною пам'яттю, кодом, даними, файлами і іншими ресурсами ОС.

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

Тут ми розглянемо можливість для організації фонових дій (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, незважаючи на пріоритет його процесу, що породив.