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

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

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

?тановка властивості

property Terminated: Boolean;

у значення True. Таким чином, Terminate це вказівка потоку завершитися, виражене в мякій формі, з можливістю коректно звільнити ресурси. Якщо вам потрібно негайно завершити потік, використовуйте функцію Windows API TerminateThread.

Примітка

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

Ще одна корисна властивість:

property FreeOnTerminate: Boolean;

Якщо це властивість рівне True, то деструкція потоку буде викликана автоматично після його завершення. Це дуже зручно для тих випадків, коли ви в своїй програмі не упевнені точно, коли саме завершиться потік, і хочете використовувати його за принципом вистрілив і забув (fire and forget).

function WaitFor: Integer;

Метод WaitFor призначений для синхронізації і дозволяє одному потоку дочекатися моменту, коли завершиться інший потік. Якщо ви усередині потоку FirstThread пишіть код

Code:= SecondThread. WaitFor;

то це означає, що потік FirstThread зупиняється до моменту завершення потоку SecondThread. Метод WaitFor повертає код завершення очікуваного потоку (див. властивість Returnvalue).

property Handle: THandle read FHandle;

property ThreadID: THandle read FThreadID;

Властивості Handle і ThreadID дають програмісту безпосередній доступ до потоку засобами API Win32. Якщо розробник хоче звернутися до потоку і управляти ним, минувши можливості класу TThread, значення Handle і ThreadID можуть бути використані як аргументи функцій Win32 API. Наприклад, якщо програміст хоче перед продовженням виконання додатку дочекатися завершення відразу декількох потоків, він повинен викликати функцію API waitForMuitipieObjects; для її виклику необхідний масив дескрипторів потоків.

property Priority: TThreadPriority;

Властивість Priority дозволяє запитати і встановити пріоритет потоків. Пріоритети потоків в деталях описані вище. Допустимими значеннями пріоритету для обєктів TThread є tpidle, tpLowest, tpLower, tpNormai, tpHigher, tpHighest і tpTimeCritical.

procedure Synchronize (Method: TThreadMethod);

Цей метод відноситься до секції protected, тобто може бути викликаний тільки з нащадків TThread. Delphi надає програмісту метод Synchronize для

безпечного виклику методів VCL усередині потоків. Щоб уникнути конфліктних ситуацій, метод synchronize дає гарантію, що до кожного обєкту VCL одночасно має доступ тільки один потік. Аргумент, передаваний в метод Synchronize, це імя методу, який виробляє звернення до VCL; виклик Synchronize з цим параметром це те ж, що і виклик самого методу. Такий метод (класу TThreadMethod) не повинен мати ніяких параметрів і не повинен повертати ніяких значень. Наприклад, в основній формі додатку потрібно передбачити функцію

procedure TMainForm. SyncShowMessage; begin

ShowMessagedntToStr (ThreadListl. Count));// інші звернення до VCL

end;

а в потоці для показу повідомлення писати не

ShowMessage (IntToStr(ThreadListl. Count));

і навіть не

MainForm. SyncShowMessage;

а тільки так:

Synchronize (MainForm. SyncShowMessage);

Примітка

Виробляючи будь-яке звернення до обєкту VCL з потоку, переконайтеся, що при цьому використовується метод Synchronize; інакше результати можуть виявитися непередбачуваними. Це вірно навіть в тому випадку, якщо ви використовуєте засоби синхронізації, описані нижче.

procedure Resume;

Метод Resume класу TThread викликається, коли потік відновлює виконання після зупинки, або для явного запуску потоку, створеного з параметром CreateSuspended, рівним True.

procedure Suspend;

Виклик методу Suspend припиняє потік з можливістю повторного запуску згодом. Метод suspend припиняє потік незалежно від коду, виконуваного потоком в даний момент; виконання продовжується з точки останову.

property Suspended: Boolean;

Властивість suspended дозволяє програмісту визначити, чи не припинений потік. За допомогою цієї властивості можна також запускати і зупиняти потік. Встановивши властивість suspended в значення True, ви одержите той же результат, що і при виклику методу Suspend припинення. Навпаки, установка властивості Suspended в значення False відновлює виконання потоку, як і виклик методу Resume.

property ReturnValue: Integer;

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

На цьому завершимо докладний огляд класу TThread. Для ближчого знайомства з потоками і класом Delphi TThread створимо багатопотоковий додаток. Для цього потрібно написати всього декілька рядків коду і кілька разів клацнути мишею.

Засоби синхронізації потоків

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

MyCompThread:= TComputationThread. Create(False);

// Тут можна що-небудь робити, поки другий потік виробляє обчислення

DoSomeWork;

// Тепер чекаємо його завершення

MyCompThread. WaitFor;

Приведена схема абсолютно недопустима, якщо під час своєї роботи потік MyCompThread звертається до VCL за допомогою методу synchronize. В цьому випадку потік чекає головного потоку для звернення до VCL, а той, у свою