Главная

Популярная публикация

Научная публикация

Случайная публикация

Обратная связь

ТОР 5 статей:

Методические подходы к анализу финансового состояния предприятия

Проблема периодизации русской литературы ХХ века. Краткая характеристика второй половины ХХ века

Ценовые и неценовые факторы

Характеристика шлифовальных кругов и ее маркировка

Служебные части речи. Предлог. Союз. Частицы

КАТЕГОРИИ:






Локальные данные потока




Как уже отмечалось ранее одно из основных удобств использования класса TThread, заключается в том, что каждый поток соответствует отдельному экземпляру объекта, и их данные не пересекаться, т.е. каждый поток работает со своими экземплярами переменных класса. Однако, если программист использует для работы с потоками API функции Windows то все потоки будут использовать одни и те же переменные. Для поддержки разделения данных между потоками на уровне функции работы с поттоками в язык Object Pascal введена специальная директива - threadvar, которая отличается от директивы описания переменных var тем, что применяется только к локальным данным потока.

Var

datal: Integer; threadvar

data2: Integer;

В приведенном примере переменная datal будет использоваться всеми потоками данного приложения, а переменная data2 будет у каждого потока своя.

Подводя итог описания работы с потоками в Delphi, отметим, что в данной среде программирования реализована очень удачная концепция работы с потоками с помощью класса TThread, значительно упрощающая разработку многопоточных приложений. Также у программиста остается возможность работать с потоками с помощью встроенных функций операционной системы, а при необходимости совмещать эти два подхода. Однако не следует совмещать и путать эти два понятия. С точки зрения операционной системы поток - это ее объект, при своем создании он получает дескриптор и отслеживается ОС. Объект класса TThread - это конструкция Delphi, соответствующая потоку ОС. Этот объект VCL создается до реального возникновения потока в системе и уничтожается после его исчезновения.

 

Упражнение

1. Запустите среду разработки Delphi, откройте новый проект через главное меню File|New|Application либо воспользуйтесь проектом, созданным по умолчанию.

2. Расположите на форме две кнопки с надписями «Start» и «Stop», для задания надписей используйте свойство Caption, для вызова страницы свойств (Object Inspector) используйте клавишу F11 (рис. 1).

Рис. 1

3. Создайте для формы обработчик события MouseDown (нажатие кнопки мыши), рисующий на форме круг в текущем положении курсора мыши. Для этого в окне Object Inspector, предварительно выделив форму, выберете закладку Events, на которой найдите событие OnMouseDown. Создайте обработчик события двойным щелчком мыши по полю.

Рис. 2

4. В обработчике события введите следующий программный код.

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

begin

Canvas.Pen.Color:=clYellow;

Canvas.Brush.Color:=clYellow;

Canvas.Ellipse (x - 30, y - 30, x + 30, y + 30);

end;

 

5. Запустите приложение на выполнение, нажав клавишу F9.

6. Добавьте константу с именем Radius и замените ей непосредственное значение радиуса 30.

7. Добавьте программный поток, выполняющий фоновую закраску формы. Для этого выполните команду File|New|Other…, на экране появится окно с шаблонами, в котором следует выбрать элемент Thread Object.

Рис. 3

8. Задайте имя создаваемого класса – TPaintThread.

Рис. 3

9. В созданном модуле (Unit2) добавьте ссылку на модуль с главной формой (Unit1) и на модуль Graphics. Для этого добавьте ключевое слово uses в разделе implementation.

implementation

uses Unit1,Graphics;

10. В модуле формы (Unit1) добавьте ссылку на модуль с потоком (Unit2), дополнив список уже используемых модулей в разделе uses.

11. Добавьте непосредственно исполняемый код потока в метод Execute класса TPaintThread.

procedure TPaintThread.Execute;

var

X, Y: Integer;

begin

Randomize;

repeat

X:= Random (Form1.Button1.Left-10);

Y:= Random (Form1.ClientHeight);

with Form1.Canvas do

begin

Lock;

Pixels [X, Y]:= clBlue;

UnLock;

end;

until Terminated;

end;

В данном случае объект Canvas (полотно для рисования на форме) будет являтся разделяемым ресурсом, т.к. к нему одновременно будут обращаться несколько потоков. Объект Canvas формы имеет встроенные средства синхронизации для предотвращения конфликтов при доступе – Lock и UnLock. В общем случае при обращении к форме из разных потоков необходимо использовать метод Synchronize.

12. Добавьте вызов методов Lock и UnLock при обращении к объекту Canvas в главной форме.

13. Объявите переменную для работы с потоком в модуле формы.

var

Form1: TForm1;

PT: TPaintThread;

14. Добавьте обработчики события Click кнопок Start и Stop.

procedure TForm1.Button1Click(Sender: TObject);

begin

Button1.Enabled:=False;

Button2.Enabled:=True;

PT:= TPaintThread.Create(False);

end;

 

procedure TForm1.Button2Click(Sender: TObject);

begin

PT.Terminate;

PT.Free;

Button1.Enabled:=True;

Button2.Enabled:=False;

end;

15. Запустите приложение на выполнение, нажав клавишу F9.

16. При завершении основного потока должны завершиться и все дочерние потоки, для этого в событии FormDestroy нужно завершить и уничтожить поток аналогично тому, как это делается при нажатии на кнопку Stop.

17. Перепишите код обращения к объекту Canvas с использованием метода Synchronize вместо вызовов методов блокировки.

 

Задание

Разработать многопоточное приложение, позволяющие динамически управлять потоками, выводящими на экран круги произвольного радиуса и цвета. Примерная экранная форма представлена на рис.

Список «Поток» содержит созданные в программе потоки. Изменение параметров «Приоритет», «Радиус» и «Цвет» применяются к выбранному потоку.

Список «Приоритет» позволяет указать приоритет потока.

 

В поле «Радиус» вводится радиус кругов, рисуемых текущим потоком.

При щелчке на поле с цветом выводится стандартное диалоговое окно для выбора цвета потока.

При нажатии на кнопку «Создать поток» создается новый поток с параметрами по умолчанию, имя потока добавляется в список потоков.

Нажатие кнопки «Завершить поток» уничтожает выбранный в списке поток и удаляет его из этого списка.

Список «Приоритет главного потока» позволяет задать приоритет потока формы.

Рекомендации

Ссылки на созданные потоки удобно хранить в динамическом массиве.

Для изменения приоритета главного потока можно использовать приведенные ниже API-функции.

MainTh:= GetCurrentThread;

SetThreadPriority(MainTh, THREAD_PRIORITY_NORMAL);






Не нашли, что искали? Воспользуйтесь поиском:

vikidalka.ru - 2015-2024 год. Все права принадлежат их авторам! Нарушение авторских прав | Нарушение персональных данных