Главная » C++, C++ Builder » Работа с потоками в форме CBuilder

0

Чтобы работать с потоком, надо его создать. Это поручается форме, содержащей поток, и осуществляется простым вызовом оператора new для создания нового объекта «поток». В нашем примере мы создадим поток при создании формы. Создайте обработчик события формы OnCreate и поместите в метод FormCreate следующий код:

void __fastcall TForm1::FormCreate(TObject *Sender)

{

pThread = new TCheckThread(FALSE); pThread->AssignLabel( Label1 );

}

Когда вы создаете поток, то у вас есть возможность создать его либо приостановленным (suspended), либо нет. Параметр конструктора потока представляет собой булевское (логическое) значение, указывающее, в каком режиме создавать поток. Приостановленный режим — это как будто вы «усыпляете» поток,  пока вам  не понадобится его «разбудить» из своего приложения. Если вы запустите поток в приостановленном режиме, то на вас ложится ответственность за вызов потока к жизни, выполняя метод Resume (продолжить) потока.

Зачем вам создавать поток в приостановленном режиме? Для этого могут быть  две  причины. Первая состоит в том, что из-за некоторых проблем у распределите ля времени Windows существует вероятность, что поток запустится до того, как закончится выполнение конструктора класса потока. Если это является проблемой для вас, то создавайте поток в приостановленном режиме, затем вызывайте метод  Resume последней операцией в конструкторе. Простой пример

такого кода выглядит так:

TMyThread::TMyThread( bool bSuspend )

: TThread (true) // приостановленный режим!

{

// Что-нибудь инициализировать

// Запустить поток, если нужно if ( bSuspend == false ) Resume();

}

Вам  нужно  решить,  надо  ли  писать  это  в  вашем  коде.  Это  очень  простой  код,  ничему  не мешающий, так что, вероятно, вы захотите всегда создавать потоки именно таким образом.

В нашем примере мы создаем поток в обычном (не приостановленном) режиме,  то есть поток запустится сразу, как только все будет для этого сделано. Мы можем так поступить, так как нам не нужны никакие особые условия для запуска потока.

Когда поток запустился, у пользователя есть несколько вариантов, как его можно остановить. Во- первых, можно остановить поток, нажав на кнопку Остановка . Чтобы остановить поток, нужно передать методу потока Execute, что он

должен остановиться. Взглянув на метод Execute, мы видим, что он завершается, когда флаг Terminated равен true (истина). Для того чтобы обратить это значение (Terminated) в истинное, вам нужно вызвать метод класса потока Terminate (остановить). Добавьте следующий обработчик нажатия на кнопку Остановка в классе формы:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

pThread->Terminate();

}

Еще один способ, каким можно (при)остановить и продолжить выполнение потока, — увидеть в действии, добавив в классе формы обработчик для кнопки Пауза:

void __fastcall TForm1::Button2Click(TObject *Sender)

{

pThread->Suspend();

}

Как видите, используется метод потока Suspend. Это временно остановит поток, но не убьет его. Метод Execute не вызывается, когда поток приостановлен. Есть  одна  странная  деталь  в отношении остановки потока методом Suspend. Вызов этого метода не является переключателем

«выключить/включить» поток. Если вызвать Suspend несколько раз, то при каждом вызове будет

нарастать  счетчик.  Чтобы  по  новой  запустить  поток,  который  останавливали  несколько  раз методом  Suspend,  вам  придется  вызвать метод  Resume  такое же  число  раз.  Процесс  выглядит

примерно так:

Suspend : Счетчик = 1 Suspend : Счетчик = 2 Suspend : Счетчик = 3

Resume : Счетчик = 2 Поток не запускается   Resume : Счетчик = 1 Поток не запускается   Resume : Счетчик = 0 Поток наконец-то запускается

Зачем вам может понадобиться несколько раз останавливать поток вызовами Suspend? Существует большое количество причин для этого, но основная заключается в том, что вы вызываете класс, унаследованный от класса потока, из класса, унаследованного от класса формы. Если у вас есть разные условия на разных уровнях наследования, при которых вы не хотите запускать поток, то вы будете вызывать метод Suspend на всех этих уровнях. Чтобы по новой запустить поток, нужно чтобы все эти уровни согласились с тем, что условия их устраивают.

Последнее действие — кнопка Продолжение . Нажатие на эту кнопку приведет к уменьшению счетчика остановок потока. Если нажать сначала на кнопку Пауза, а затем на кнопку Продолжение

, то вы увидите, что поток сначала перестал выводить числа на экран, а затем продолжил свое занятие. Создайте обработчик нажатия на кнопку Продолжение и добавьте в него следующий код:

void __fastcall TForm1::Button3Click(TObject *Sender)

{

pThread->Resume();

}

Вот, в общем-то, и все, что вам нужно знать о работе с потоками  в  форме.  CBuilder  делает общение с потоками чрезвычайно простым, так что вам почти ничего не нужно знать о том, что происходит за кулисами работы с потоками. Важными моментами в данном примере являются следующие: поток должен быть создан, для потока должно быть задано условие выхода, и поток должен быть остановлен. Кроме того, если вы помните о том, что надо использовать метод Synchronize для общения потока с объектами VCL в форме, то вы знаете все, что нужно для программирования  потоков.

Просто чтобы показать вам, что ничего сложного здесь нет, мы разберем гораздо более суровый пример работы с потоками.

Источник: Теллес М. – Borland C++ Builder. Библиотека программиста – 1998

По теме:

  • Комментарии