«Машины должны работать. Люди должны думать»
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. Приложения, процессы и потоки»