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

Працюючи в Delphi, програміст може також використовувати об'єкт типу критична секція (critical section). Критичні секції подібні взаємним виключенням по суті, проте між ними існують дві головні відмінності:

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

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

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

Візьмемо клас TCriticalSection (модуль SYNCOBJS.PAS). Логіка використовування його проста – «тримати і не пущать». У багатопотоковому додатку створюється і ініціалізується загальна для всіх потоків критична секція. Коли один з потоків досягає критично важливої ділянки коду, він намагається захопити секцію викликом методу Enter:

MySection. Enter; try DoSomethingCritical;

finally

MySection. Leave;

end;

Коли інші потоки доходять до оператора захоплення секції Enter і знаходять, що вона вже захоплена, вони припиняються аж до звільнення секції першим потоком шляхом виклику методу Leave. Зверніть увагу, що виклик Leave поміщений в конструкцію try..finally – тут потрібна стовідсоткова надійність. Критичні секції є системними об'єктами і підлягають обов'язковому звільненню – втім, як і решта об'єктів, що розглядаються тут.

Процес. Породження дочірнього процесу

Об'єкт типу процес (process) може бути використаний для того, щоб припинити виконання потоку в тому випадку, якщо він для свого продовження потребує завершення процесу. З практичної точки зору така проблема встає, коли потрібно в рамках вашого додатку виконати додаток, створений кимось іншим, або, наприклад, сеанс MS-DOS.

Розглянемо, як, власне, один процес може породити інший. Замість застарілої і підтримуваної тільки для сумісності функції winExec, що перекочувала з колишніх версій Windows, набагато правильніше використовувати могутнішу:

function CreateProcess (IpApplicationName: PChar; IpCorranandLine: PChar;

IpProcessAttributes, IpThreadAttributes: PSecurityAttributes;

blnheritHandles: BOOL;

dwCreationFlags: DWORD; IpEnvironment: Pointer;

IpCurrentDirectory: PChar;

const IpStartupInfo: TStartupInfo;

var IpProcessInformation: TProcessInformation): BOOL;

Перші два параметри ясні – це ім'я додатку, що запускається, і передавані йому в командному рядку параметри. Параметр dwCreationFlags містить прапори, що визначають спосіб створення нового процесу і його майбутній пріоритет. Використані в приведеному нижче лістингу прапори означають: CREATE_NEW_CONSOLE – будет запущено новий консольний додаток з окремим вікном; NORMAL_PRIORITY_CLASS – нормальний пріоритет.

Структура TStartupInfo містить відомості про розмір, колір, положення вікна створюваного додатку. У нижченаведеному прикладі (лістинг 29.1) використовується поле wshowwindow: встановлений прапор SW_SHOWNORMAL, що означає візуалізацію вікна з нормальним розміром.

На виході функції заповнюється структура IpProcessInformation. У ній програмісту повертаються дескриптори і ідентифікатори створеного процесу і його первинного потоку. Нам знадобиться дескриптор процесу – в нашому прикладі створюється консольний додаток, потім відбувається очікування його завершення. «Просигналить» нам про це саме об'єкт IpProcessInformation.hProcess.

Лістинг 29.1. Породження дочірнього процесу

var

IpStartupInfo: TStartupInfo;

IpProcessInformation: TProcessInformation;

begin

FillChar (IpStartupInfo, Sizeof(IpStartupInfo), 10);

К-во Просмотров: 350
Бесплатно скачать Реферат: Робота з "потоками" в середовищі Delphi