1 / 14

Потоки в Delphi

Потоки в Delphi.

maxine-dyer
Télécharger la présentation

Потоки в Delphi

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Потоки в Delphi Потоки в Delphi выполняют функцию имитации псевдопараллельной работы приложения. Как известно, для организации многозадачности операционная система выделяет каждому приложению, выполняющемуся в настоящий момент, определённые кванты времени, длина и количество которых определяется его приоритетом. Поэтому объём работы, который приложение может выполнить, определяется тем, сколько таких квантов оно сможет получить в единицу времени. Для операционной системы каждый поток является самостоятельной задачей, которой выделяются кванты времени на общих основаниях. Поэтому приложение Delphi, умеющее создать несколько потоков, получит больше времени операционной системы, и соответственно сможет выполнить больший объём работы.

  2. Потоки в Delphi Создать дополнительный поток в Delphi поможет объект TThread. Ввести объект TThread в программу можно двумя способами: с помощью Мастера; вручную. 1. Мастер создания дополнительного потока в Delphi создаёт отдельный модуль, в рамках которого выполняется поток. Выполним:File -> New -> Other...В появившейся табличке выбора найдём TThreadObject. Появится окошко, в верхнюю строку которого (ClassName) введём имя нашего будущего потока: MyThread. В результате будет создан модуль, содержащий заготовку кода, реализующего дополнительный поток Delphi

  3. Потоки в Delphi unit Unit2; // Имя модуля, содержащего поток. При сохранении его можно изменить.Interfaceuses  Classes;typeMyThread = class(TThread) //MyThread - имя потока.private    { Private declarations }  protected    procedure Execute; override;  end;implementation{ Important: Methods and properties of objects in visual components can only be  used in a method called using Synchronize, for xample,      Synchronize(UpdateCaption);  and UpdateCaption could look like,    procedure MyThread.UpdateCaption;    begin      Form1.Caption := 'Updated in a thread';    end; }{ MyThread }procedure MyThread.Execute;begin  { Place thread code here }end;end.

  4. Потоки в Delphi В первом способе класс MyThreadбыл создан мастером в дополнительном модуле. Второй способ состоит в том, что мы сами создаём такой класс в рамках одного из уже существующих модулей программы, например, в модуле Unit1: unit Unit1; //Обычный модуль в котором описывается основная программаinterfaceuses  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;type  TForm1 = class(TForm)    Button1: TButton;    procedure Button1Click(Sender: TObject);private{ Private declarations }public{ Public declarations }end;//Здесь необходимо описать класс TMyThread:TMyThread = class(TThread)private{ Private declarations }protectedprocedure Execute; override;end;

  5. Потоки в Delphi var  Form1: TForm1;//Нужно ввести переменную класса TMyThreadMyThread: TMyThread;implementation{$R *.dfm}//Нужно создать процедуру Execute, уже описанную в классе TMyThreadprocedureTMyThread.Execute;begin//Здесь описывается код, который будет выполняться в потокеend;

  6. Потоки в Delphi Если поток создаётся мастером, т.е. в другом модуле, то не забудьте в основном модуле описать переменную - экземпляр потока. Также, поскольку класс потока описан в другом модуле, имя этого модуля необходимо добавить в секцию uses. Теперь можно запускать поток, даже если в его процедуре Execute нет ни единого оператора. //Запускать поток будем нажатием на кнопку:procedure TForm1.Button1Click(Sender: TObject);begin//Вначале нужно создать экземпляр потока:MyThread:=TMyThread.Create(False);//Параметр False запускает поток сразу после создания, True - запуск впоследствии , методом Resume//Далее можно указать параметры потока, например приоритет:MyThread.Priority:=tpNormal;end;end.

  7. Потоки в Delphi Применение потоков Если в основной программе попробовать выполнить такой цикл: whileTruedo; то приложение зависнет. А теперь поместите его в процедуру Execute. При нажатии на кнопку наш бесконечный цикл будет непрерывно выполняться в потоке, однако и приложение как целое не зависнет.procedureTMyThread.Execute;beginwhileTruedo; end;    В предыдущем примере поток выполняет бесконечный цикл. Однако, поток также обладает возможностями, позволяющими из основной программы передать ему приказ прекратить работу.

  8. Потоки в Delphi Метод потока Terminate устанавливает свойство Terminated потока в True. Анализируя это свойство, поток может понять, что он должен завершить работу. Пример:procedureTMyThread.Execute;beginwhileTruedoifMyThread.Teminatedthenbreak;end;   Этот код выполняет бесконечный цикл. Однако, при выполнении в основной программе оператораMyThread.Terminate;цикл завершается, и поток прекращает свою работу.

  9. Потоки в Delphi • При работе с потоками необходимо учитывать приоритет создаваемых потоков. Так, если в предыдущем примере запустить не один поток, а два или больше, нажав на кнопку несколько раз, то компьютер станет очень заметно "тормозить". Это происходит потому, что приоритет по умолчанию новых потоков - нормальный. Можно уменьшить его, задав • MyThread.Priority:=tpLower; • Этого достаточно, чтобы компьютер чувствовал себя более свободно. • tpIdle Низший приоритет. Поток получает время только тогда, когда операционая система находится в состоянии простоя. • tpLowest Приоритет на два пункта ниже нормального • tpLower Приоритет на один пункт ниже нормального • tpNormal Нормальный приоритет • tpHigher Приоритет на один пункт выше нормального • tpHighest Приоритет на два пункта выше нормального • tpTimeCritical Максимальный приоритет. Приоритет на уровне функций ядра операционной системы.

  10. Потоки в Delphi При использовании в приложении нескольких потоков необходимо гарантировать, что в данный момент только один из потоков может иметь доступ к свойствам и методам объекта VCL - визуального компонента Delphi, то есть действия потоков необходимо синхронизировать между собой. Для выполнения такой синхронизации в Delphi применяется специальный метод Synchronize, в рамках которого и нужно вызывать процедуры, модифицирующие свойства визуальных компонентов. Процедура Synchronize использует в качестве параметра те процедуры, в которых происходит модификация свойств визуальных компонентов, и блокирует одновременный доступ к компоненту нескольких потоков. Вот какой пример, в частности, содержится в модуле, сгенерированном Мастером создания потока: {Важно: Методы и свойства объектов в визуальных компонентах могут вызыватьсятолько в методе Synchronize, например:}procedureMyThread.UpdateCaption;begin  Form1.Caption := 'Updatedinathread';end;procedureMyThread.Execute;beginSynchronize(UpdateCaption);end;

  11. Потоки в Delphi В данном случае поток используется для изменения заголовка Формы. Изменение заголовка происходит в процедуре UpdateCaption. Казалось бы, для изменения заголовка эту процедуру достаточно вызвать в основной процедуре потока, Execute. Однако, если несколько таких потоков в программе одновременно попытаются изменить заголовок Формы, то это может привести к непредсказуемым последствиям. Для исключения этого процедура UpdateCaption вызывается в процедуре Execute как параметр метода Synchronize.  Нужно знать, что метод Synchronize выполняется в главном потоке приложения. Поэтому, работая с несколькими потоками в приложении и применяя метод Synchronize, нужно учитывать, что: во-первых, частый вызов Synchronize тормозит выполнение приложения; во-вторых, если практически все процедуры выполняющегося потока выполняются с использованием метода Synchronize, то смысла в создании такого потока нет - всё равно его работа пройдёт в главном потоке.

  12. Потоки в Delphi Как пример рассмотрим всё ту же модификацию заголовка Формы. Пусть в одном из потоков происходит работа с большим массивом, и требуется отображать какой объём массива уже обработан. Для этого организуем поток, который будет выполнять эту работу. Будем выводить в заголовок Формы индекс элемента, с которым обрабатывающий поток работает в данный момент. Делать это будем с периодичностью 10 раз в секунду. Сначала сделаем так: procedureTMyThread.UpdateCaption;beginwhileTruedobegin    Form1.Caption:=IntToStr(I);//I - глобальная переменная основной //программы, индекс массиваsleep(100);end;end;procedureTMyThread.Execute;beginSynchronize(UpdateCaption);end;

  13. Потоки в Delphi Видим, что происходит именно то, о чём написано выше. Так как весь код потока, и модификация заголовка Формы, и цикл ожидания, выполняется в методе Synchronize, а значит в главном потоке, то приложение будет выглядеть зависшим, и его даже будет невозможно корректно завершить. Теперь попробуем вывести цикл за пределы Synchronize: procedureTMyThread.UpdateCaption;begin  Form1.Caption:=IntToStr(Cap);end;procedureTMyThread.Execute;beginwhileTruedobeginSynchronize(UpdateCaption);sleep(100);end;end; Это правильный вариант. С помощью метода Synchronize выполняется только непосредственная модификация Заголовка Формы, а цикл ожидания выполняется в потоке, и не мешает главному потоку.

  14. Потоки в Delphi • Некоторым объектам VCL процедура Synchronize не требуется, так как они всё же умеют корректно работать с потоками, либо нуждаются в других методах синхронизации. • Так, корректно работают с потоками • компоненты доступа к базам данных (с использованием компонентов класса TSession). Исключение составляют базы данных MicrosoftAccess; • классы, которые работают непосредственно с графикой. Это TFont, TPen, TBrush, TBitmap, TMetafile и TIcon. Канву объектов этих классов (Canvas) можно использовать не применяя метод Synchronize. Это делается с помощью блокировки канвы. То есть, поток, использующий в данный момент канву, предварительно блокирует канву методом Lock, препятствующим другим потокам работать с канвой, и разблокирует затем методом UnLock.

More Related