русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Создание многопоточных приложений

Для организации параллельных процессов в Delphi предусмотрен особый тип данных Thread (поток). Название "поток" в данном случае не имеет ничего общего с файловым потоком (см. п. 13.5. на с. 111). Надо отметить, что работа с потоками достаточно сложна и неочевидна.

Создадим программу, выполняющую простейшее действие – сложение двух введенных чисел. Создаем новое приложение и сохраняем файл программы под именем unit1.pas (это важно!), а файл проекта – project1.dpr. Поместим на форму два компонента типа Tedit, кнопку и компонент Tlabel. В обработчике нажатия на кнопку напишем очевидный код:

procedure TForm1.Button1Click(Sender: TObject);

var a,b:real;

begin

TRY

a:=StrToFloat(Edit1.Text);

b:=StrToFloat(Edit2.Text)

EXCEPT

MessageDlg('Неверные данные', mtError,[mbOK],0);

EXIT

END;

Label2.Caption:=FloatToStr(a+b)

end;

А теперь заставим цвет формы плавно меняться, перебирая все возможные оттенки. Цвет формируется значениями интенсивности красного, синего и зеленого. Интенсивность каждого цвета хранится в одном байте и соответственно принимает значения от 0 до 255. Поэтому для перебора всех цветов можно использовать три вложенных цикла:

for red:=0 to 255 do

for green:=0 to 255 do

for blue:=0 to 255 do

begin

form1.Color:=RGB(Red,Green,Blue);

application.ProcessMessages

end;

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

Для создания потока выполним команду меню FileàNewàOtheràThread Object (). В появившемся окошке следует ввести произвольное имя потока, к примеру, Time. Delphi автоматически создаст файл-заготовку для потока с описанием вида

type

Time = class(TThread)

private

{ Private declarations }

protected

procedure Execute; override;

end;

Сразу сохраним файл-заготовку под именем unit2.pas. Поток имеет процедуру Execute, внутри которой и вызывается код, исполняемый в потоке. Однако из процедуры Execute нельзя напрямую обращаться к компонентам. Это связано с тем, что в многопоточном приложении несколько потоков могут одновременно захотеть изменить одно и то же свойство одного и того же компонента. Скажем, при отрисовке, один и тот же пиксел один поток требует окрасить в черный цвет, а другой – в белый. Для исключения подобных коллизий необходимо применять так называемую синхронизацию потоков. Синхронизация обеспечивает последовательный доступ потоков к свойствам компонентов и позволяет избежать конфликтов.

Для синхронизации, прежде всего надо весь код, изменяющий свойства компонентов, вынести в отдельную процедуру. Чтобы в модуле unit2.pas можно было "видеть" форму, описанную в модуле unit1.pas и, наоборот, в операторы USES надо добавить ссылки модулей друг на друга. В файле unit1.pas в самом начале в конец списка модулей в операторе USES добавим unit2. А вот в файле unit2.pas так сделать не удастся – Delphi запрещает ситуацию, когда два модуля ссылаются друг на друга (так называемая "круговая ссылка"). Что же делать? Выход очень простой: ввести ссылку в раздел Implementation:


Implementation

uses unit1, Windows, Forms;

Как видно из примера, приходится вручную прописывать и ссылки на библиотечные модули Windows (в нем хранится функция RGB) и Forms (в нем хранится переменная Application).

Цикл смены цветов будет выполняться бесконечно, но надо предусмотреть возможность его останова при завершении работы программы. В модуле unit1 объявим глобальную переменную br:

var

Form1: TForm1;

Thread: Time;

br:BOOLEAN=false;

Здесь же объявим и переменную Thread, которая будет представлять дочерний поток в программе.

Переменная br должна устанавливаться в True при запросе пользователя на закрытие формы. Для этого создаем обработчик события формы OnCloseQuery:

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);

begin

br:=true

end;

В модуле unit2 в класс Time добавляем заголовок нашей будущей процедуры:

type

Time = class(TThread)

private

{ Private declarations }

procedure Show; { эту строчку дописать }

protected

procedure Execute; override;

end;

Далее пишем саму процедуру Show:

procedure Time.Show;

var red, green, blue:byte;

begin

for red:=0 to 255 do

for green:=0 to 255 do

for blue:=0 to 255 do

begin

form1.Color:=RGB(Red,Green,Blue);

application.ProcessMessages;

if br then exit

end

end;

Оператор If обеспечивает выход из процедуры при закрытии программы. Осталось организовать синхронный вызов процедуры Show. В заготовке процедуры Execute пишем:

procedure Time.Execute;

begin

{ Place thread code here }

repeat

Synchronize(Show)

until terminated;

end;

Здесь цикл Repeat..Until вызывает метод Synchronize, который, в свою очередь, синхронно и корректно выполняет нашу процедуру Show. Цикл прекращается при завершении потока, когда его свойство Terminated устанавливается в True.

В модуле unit1 осталось организовать запуск потока и прекращение его работы. Пишем обработчик события создания формы OnCreate:

procedure TForm1.FormCreate(Sender: TObject);

begin

DoubleBuffered:=TRUE;

Thread:=Time.Create(false);

Thread.FreeOnTerminate:=true;

Thread.Priority:=tpLower

end;

Поток создается вызовом метода Create. Параметр False указывает на то, что поток начнет исполняться немедленно после создания. Свойство FreeOnTerminate, будучи установленным в True, автоматически освобождает занятую потоком память после завершения его работы. Свойство Priority указывает, какая доля процессорного времени отводится на выполнение потока. Возможны следующие варианты:

Табл. 22.1

Константа Описание
tpIdle Поток выполняется, только если приложение находится в режиме ожидания и ничего не делает
tpLowest Приоритет на два уровня ниже нормального
tpLower Приоритет на один уровень ниже нормального
tpNormal Нормальный приоритет
tpHigher Приоритет на один уровень выше нормального
tpHighest Приоритет на два уровня выше нормального
tpTimeCritical Наивысший приоритет

Установка приоритета прямо влияет на скорость выполнения потока. При установке высоких приоритетов поток начинает "тормозить" как основную программу, так и всю операционную систему.

При завершении работы программы необходимо завершить и поток. В обработчик события OnCLoseQuery допишем строчку Thread.Terminate:

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);

begin

br:=true;

Thread.Terminate

end;

Готово! Запускаем программу и видим, как непрерывно меняется фон формы, не мешая при этом выполнять вычисления.

Просмотров: 578


Вернуться в оглавление



Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.