Простий приклад потоку в CBuilder

У нашому першому прикладі ми почнемо з внутрішніх особливостей роботи з потоками Ми створимо просту форму, яка використовує потік для оновлення тексту на екрані Форма дозволить вам призупиняти (pause), знову запускати (resume) і зупиняти (stop) виконання потоку Водночас потік буде відображати числа на екрані Ми досліджуємо процес створення потоку і додавання обєкта «потік» у вашу програму

На рис 131 показана форма, яку ми будемо використовувати в даному прикладі потоку Як бачите, на ній знаходиться одна мітка і три кнопки

Рис 131 Форма простого прикладу потоків

Насамперед в додатку, що використовує потоки, було б непогано дізнатися, як же додати потік Ви, напевно, бачили клас TThread в документації до CBuilder Цей клас служить для представлення потоків в системі На жаль, додавання нового потоку трохи складніше, ніж створення нового обєкта «потік» оператором new

Потоки містять метод, який реалізує всю необхідну обробку потоку Цей метод (Execute) Викликається при старті потоку і повинен працювати, поки потік живий Коли метод Execute повертає управління, то потік виходить або вмирає Таким чином, вам потрібно перевизначити метод Execute так, щоб він робив те, що вам потрібно Але щоб можна було перевизначити метод, вам необхідно успадкувати свій власний клас від класу TThread, І саме цим ми і займаємося Ви визначите клас, наслідуваний від TThread, І напишете метод Execute для цього породженого класу

У CBuilder дуже легко створювати класи, успадковані відTThread, Створюючи новий обєкт

«Потік» Для цього виберіть команду File д New і елемент Thread Object (потоковий обєкт) на першій сторінці діалогу New Items При виборі цього обєкта зявиться вторинне вікно діалогу із запитом про новий імені вашого потокового класу У даному випадку вкажіть імя TCheckThread, Так як ми будемо перевіряти деяке значення і відображати його Коли ви натиснете на кнопку OK, клас TCheckThread згенерує у вихідному файлі Unit2cpp (а також в заголовному файлі Unit2h) Ось так виглядає цей клас, згенерований CBuilder:

//——————————————————

#include &ltvcl\vclh&gt

#pragma hdrstop

#include &quotUnit2h&quot

//——————————————————

// Important: Methods and properties of objects in VCL can

// only be used in a method called using Synchronize,

// for example:

//  Synchronize(UpdateCaption)

// where UpdateCaption could look like:

//

// void      fastcall TCheckThread::UpdateCaption()

// {

// Form1-&gtCaption = &quotUpdated in a thread"

// }

//—————————————————–

__fastcall TCheckThread::TCheckThread(bool CreateSuspended)

: TThread (CreateSuspended)

{

}

//—————————————————–

void __fastcall TCheckThread::Execute()

{

//—- Place thread code here —-

}

//—————————————————–

Як бачите, потоковий клас, згенерував майстром, описаний дуже повно Він нічого не робить, але готовий до роботи Щоб він щось робив, вам потрібно тільки лише написати метод Execute

У нашому першому прикладі цікаво було б вивчити різні методи класу потоку Саме тому наш метод Execute вкрай простий, він вважає до 10000 знову і знову Ми хочемо проілюструвати швидкість роботи коду потоку, звязок потоку з навколишнім світом і навчити вас писати код потоку Тримаючи все це в розумі, додайте наступний код в метод Execute:

void __fastcall TCheckThread::Execute()

{

while ( Terminated )

{

Synchronize(UpdateLabel1)

}

MessageBox (NULL, Все зроблено”, Інформація, MB_OK)

}

Крім методу Execute, Нам потрібно ще оновити два методи По-перше, конструктор класу Ось код ініціалізації, який потрібно додати в конструктор:

__fastcall TCheckThread::TCheckThread(bool CreateSuspended)

: TThread (CreateSuspended)

{

pLabel = NULL nCount = 0

}

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

void __fastcall TCheckThread::AssignLabel(TLabel *pL)

{

pLabel = pL

}

Метод Synchronize надає вам спосіб уникнути всіх цих проблем, повязаних з багатопоточність, коли один і той же обєкт намагаються змінити з різних потоків у додатку Коли ви працюєте в головному потоці (самому додатку) з обєктом VCL, то вам

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

У методу Synchronize єдиний аргумент типу TThreadMethod Це просто покажчик на функцію-член класу потоку, у якої немає параметрів і яка нічого не повертає Ця функція повинна бути якомога більш швидкої, щоб взаємодія між потоками відбувалося безболісно При виклику Synchronize буде працювати тільки переданий метод, і нічого більше

Отже, весь цей код призводить до виклику методу UpdatLabel, Який власне і робить всю роботу в класі потоку Це вельми простий метод, як видно з лістингу:

void __fastcall TCheckThread::UpdateLabel(void)

{

if ( pLabel )

pLabel-&gtCaption = nCount if ( nCount &lt 10000 ) nCount ++

else

nCount = 0

}

Тепер, маючи весь цей код класу потоку, пора модифікувати клас форми: створювати потік, а потім працювати з ним Давайте звернемо нашу увагу на цю задачу

Джерело: Теллес М – Borland C + + Builder Бібліотека програміста – 1998

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*