«Любой дурак может написать программу, которую поймет компилятор. Хорошие программисты пишут программы, которые смогут понять другие программисты»
39. Класс TThread
Несмотря на то, что Win32 API включает все средства, необходимые для работы с потоками, класс TThread удобнее использовать в частности потому, что он предоставляет средства, гарантирующие совместимость с библиотекой визуальных компонентов Delphi.
Для создания потока необходимо выполнить следующие действия:
Ø создать новый проект, разместить на форме все необходимые компоненты и добавить требуемый код;
Ø выполнить тему меню File/New/Thread Object, задать имя класса поток. После выполнения этих действий Delphi создаст новый модуль-шаблон для потока;
Ø сохранить этот модуль под требуемым именем в папке проекта;
Ø новый модуль добавить в предложение uses там, гже это необходимо;
Ø добавить в модуль (потока) требуемый код.
В сгенерированном Delphi модуле-заготовке присутствует описание класса TThread с одним единственным методом Execute. С этого метода, который нет необходимости вызывать "напрямую", начинается выполнения потока. Но еще раньше поток необходимо создать с помощью конструктора Create.
Класс TThread является производным от класса TObject и включает 9 методов, приведенных в таблице.
Метод |
Назначение |
Create |
Конструктор потока с одним параметром булевского типа CreateSuspended (suspended – приостановленный). Если этот параметр равен false, поток сразу начинает выполняться с метода Execute, а в противном случае выполнение потока должно быть начато с вызова метода Resume |
Destroy |
Деструктор, который редко вызывается непосредственно |
Execute |
Абстрактный метод, с которого начинается выполнение потока. Выполнение потока прекращается, когда завершается выполнение этого метода |
Suspend |
Приостанавливает выполнение потока с возможностью возобновления его выполнения с прерванной точки с помощью метода Resume |
Resume |
Возобновляет выполнение приостановленного потока с точки, в которой он был приостановлен |
DoTerminate |
Генерирует событие OnTerminate, но не прекращает выполнение потока |
Terminate |
Прекращает выполнение потока. Этот метод, при необходимости, может быть вызван для прекращения потока, но это редко делается |
Synchronize |
Обеспечивает безопасный вызов методов VCL внутри потоков |
WaitFor |
Этот метод позволяет дождаться завершения потока и получить код результата ReturnValue |
Перечень свойств класса TThread приведен в таблице.
Свойство |
Описание |
FreeOnTerminate : boolean |
Если требуется автоматическое уничтожение потока после его завершения, это свойство должно быть установлено в true. Если оно установлено в false, то требуется самостоятельно вызывать деструктор |
Handle : integer |
Описатель потока, который необходим при манипуляциях с потоком с помощью функций Win32 API |
Priority |
Приоритет потока |
ReturnValue : integer |
Код результата завершения потока, устанавливаемый программистом. Его значение может получить процесс или другой поток с помощью метода WaitFor |
Suspended : boolean |
Приостанавливает выполнение потока (true). Для возобновления выполнения потока необходимо установить его в false (или вызвать метод Resume) |
Terminated : boolean |
Значение true указывает на то, что поток должен завершить работу. Значение этого свойства следует анализировать в методе Execute для того, чтобы (преждевременно) завершить поток |
ThreadID : integer |
Идентификатор потока, который полезен при отладке и необходим при использовании функций Win32 API. Он не совпадает с описателем Handle |
Реализация (абстрактного) метода Execute может выглядеть примерно так:
Procedure TMyThread.Execute;
Begin
repeat
{выполнение требуемого кода}
until CancelCondition or Terminated;
End;
Изменение значения свойства Suspended аналогично вызову методов Resume и Suspend, т.е. выполнение оператора Suspended:=true приводит к приостановке выполнения потока, а Suspended:=false – к возобновлению его выполнения с точки останова.
Метод Synchronize гарантирует, что к любому объекту VCL одновременно получит доступ только один поток. Одновременный доступ к объекту VCL двух и более потоков может вызвать непредсказуемые последствия. Метод потока, который содержит обращение к какому-либо объекту VCL, не может иметь параметров и должен быть передан процедуре Synchronize в качестве параметра, например:
Procedure ShowNumber;
Begin
Edit1.Text:=IntToStr(Number);
End;
…
Synchronize(ShowNumber);
Еще один способ синхронизации выполнения потоков можно реализовать с помощью функции
Function WaitFor : integer;
Например, при наличии потоков Thread1 и Thread2 выполнение в потоке Thread1 оператора
Code:=Thread2.WaitFor
приведет к приостановке выполнения потока Thread1 до завершения потока Thread2, а значение переменной Code будет установлено равным Thread2.ReturnValue.
К другим средствам синхронизации потоков относятся:
Ø события (класс TEvent);
Ø взаимные исключения (Mutex). Пример реализации этого класса есть в проекте ..\Demos\IPCDemos;
Ø критические секции (см. файл ..\Source\VCL\SyncObjs.pas);
Ø оповещение об изменении в файловой системе (FindFirstChangeNotification и другие
«38. Приложения, процессы и потоки»