Студопедия

КАТЕГОРИИ:

АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника


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




Далее мы рассмотрим пример, в котором в рамках программы, содержащей формы с двумя областями рисования (TPaintBox), запускаются два потока, каждый из которых выполняет рисование в своей области и со своей скоростью.

Создадим новое приложение командой File >• New > Application (Файл >• Создать >Приложение). Подготовим форму с двумя областями рисования TPaintBox размером 100x100 пикселов. Разместим также на форме кнопку, по щелчку на которой запускаются потоки (рис. 8.9).

 

Добавим в проект класс-поток командой File > New > Other > Thread Object (Файл >• Создать >• Другое > Потоковый объект). В диалоговом окне ввода названия класса укажем TMyThread. Этот класс будет наследником базового класса-потока TThread. Возникнет файл с пустым описанием этого класса.

Перейдем к модулю главной формы и опишем в классе TForml новый метод CPaint, который получит в качестве параметра холст и нарисует на нем квадрат размером 10x10 пикселов. Место расположения квадрата и его цвет выбираются случайным образом.

procedure TForml .CPaint ( Cv: TCanvas );

var b: byte,-

C: TColor;

r: TRect;

Begin

Cv.Brush.Style := bsSolid;

с := random(256);

b := random(256);

с := с or (b ehl8);

b := random(256);

с := с or {b shl16);

Cv.Brush.Color := c;

r.left := random(90);

r.top := random(90),•

r.right := r.left+10;

r.bottom := r.top+10;

Cv.Rectangle(r);

end;

На деталях реализации этой процедуры останавливаться не станем.

Добавим еще два метода (процедуры без параметров), которые будут обращаться к процедуре CPaint для вывода квадрата либо на холст объекта PaintBoxl, либо на холст объекта PaintBox2.

procedure TForml.Paintl;

Begin

CPaint( PaintBoxl.Canvas );

продолжение &

15 3ar.MB

procedure TForml.Paint2;

begin

CPaintf PaintBox2.Canvas );

end;

Эти процедуры необходимы, чтобы вызывать их из класса-потока, причем специальным образом. Дело в том, что, когда методы классов Delphi 7 (в нашем случае —метод Rectangle) одновременно вызываются из нескольких потоков, это может приводить к самым неожиданным конфликтам между потоками. Например, проблемы могут быть связаны со слишком быстрым чередованием обработки процесса вывода на экран, когда системе требуется обрабатывать объекты классов

Процесса вывода на экран, когда системе требуется обрабатывать объекты классов TBrush, ТРеп.

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

type TThreadMethod = procedure of object;

procedure Synchronize (Method: TThreadMethod) ,-

В качестве параметра он получает название метода без параметров. Для этого нам и понадобилось создать процедуры Paintl и Paint2. А как определить внутри потока, какой из этих методов надо вызывать? Добавим в класс TMyThread переменную Boxl.

public

Boxl: boolean;

end;

При создании экземпляра потока занесем в эту переменную значение True, если надо вызывать метод Paintl. Вся логика работы потока описывается в его основном методе.

procedure Execute;

Нам надо переопределить этот метод следующим образом.

procedure TMyThread.Execute;

begin

while not Terminated do

ifBoxl then Synchronise (Forrnl.Paintl)

else Synchronize(Forml.Paint2)

end;

Свойство класса Terminated автоматически примет значение True, когда программа получит команду на завершение. В зависимости от значения переменной Boxl выполнится отрисовка одного квадрата (вызов соответствующего метода класса TForml),после чего продолжится цикл произвольной длительности.

Теперь надо добавить в описание класса TForm 1 две новые переменные — два будущих

потока.

Tl, T2: TMyThread;

Опишем обработчик щелчка на кнопке Buttonl. .

procedure TForml. ButtonlClick (Sender: TObjectl ,-

begin

Tl := TMyThread.Create (true) ,-

Tl.Boxl := true;

Tl. Priority := tpLower;

T2 := TMyThread.Create(true);

T2.Boxl := false;

T2-Priority := tpLowest;

Tl.Resume;

T2.Resume;

end;

Поток создается с помощью конструктора Create, который имеет один параметр.

Он имеет значение True, если поток начинает работу после вызова метода Resume,

В противном случае (False) поток начнет работу сразу же после создания.

Далее задаются значения переменной Boxl и свойства Priority — приоритета выполнения потока. Приоритет определяет, как часто Windows выделяет процессу кванты времени, то есть фактически задает быстродействие этого процесса.

Свойство Priority имеет тип TThreadPriority и может принимать одно из следующих значений.

Таблица 8.2. Значения свойства Priority

ЗначениеПриоритет потока

tpldle Поток выполняется, только когда системе Windows больше нечего делать

tpLowest Приоритет на два пункта ниже нормального

tpLower Приоритет на один пункт ниже нормального

tpNormal Нормальный приоритет

tpHigher Приоритет на один пункт выше нормального

tpHighest Приоритет на два пункта выше нормального

tpTimeCritical Максимальный приоритет

В раздел interface модуля Unitl нужно добавить ссылку на модуль Unit2, где описан класс

TMyThread, а в раздел implementation модуля Unit? — ссылку на модуль Unitl. Программу

можно откомпилировать и запустить. После щелчка на кнопке начнется заполнение двух

областей рисования небольшими прямоугольниками, причем в правой области это будет про-

исходить заметно медленнее.

 


Поделиться:

Дата добавления: 2015-04-11; просмотров: 146; Мы поможем в написании вашей работы!; Нарушение авторских прав





lektsii.com - Лекции.Ком - 2014-2024 год. (0.005 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав
Главная страница Случайная страница Контакты