
- •Основы программирования
- •Введение
- •Основы delphi
- •Общая технология программирования
- •Язык программирования
- •Объектно-ориентированное программирование
- •Визуальное программирование
- •Событийно управляемое программирование
- •Windows-приложение
- •Среда программирования
- •Первоначальные сведения о проекте приложения
- •Встроенный отладчик
- •Использование встроенных классов
- •Иерархия классов
- •Использование палитры компонентов и инспектора объектов
- •Использование графики
- •Основные инструменты
- •Основные характеристики шрифтов
- •Графические данные и палитра
- •Некоторые общие свойства компонентов
- •Сохранение проекта
- •Построение простейшего проекта
- •Понятие исключительной ситуации
- •Введение в object pascal
- •Структура приложения
- •Структура программы-проекта
- •Структура модуля
- •Пример 1
- •Описания программных элементов
- •Программные элементы и адреса памяти
- •Области видимости
- •Правила записи имен
- •Время жизни идентификаторов
- •Использование локальных переменных в примере 1
- •Использование глобальных переменных в примере 1
- •Простые типы
- •Целые типы
- •Целые типы
- •Некоторые операции с целым типом
- •Символьные типы
- •Логические типы
- •Тип перечень
- •Интервальный тип
- •Вещественный тип
- •Вещественные типы
- •Некоторые операции с вещественным типом
- •Тип дата-время
- •Выражения
- •Константы
- •Типизированные константы.
- •Переменные
- •Операции
- •Унарная операция not (отрицание)
- •Логические операции and, or, xor
- •Функции
- •Порядок вычисления выражений
- •Виды операторов
- •Простые операторы
- •Составной оператор
- •Операторы условного перехода
- •Оператор if
- •Пример 2
- •Оператор case
- •Пример 3
- •Использование enter в примере 3
- •Операторы цикла
- •Оператор цикла for
- •Пример 4
- •Оператор цикла while
- •Пример 5
- •Оператор цикла repeat
- •Пример 6
- •Использование процедур break и continue
- •Пример 7
- •Массивы
- •Статические массивы
- •Динамические массивы
- •Пример 8
- •Пример 9
- •Записи (объединения)
- •Оператор with
- •Пример 10
- •Совместимость и преобразование типов данных
- •Идентичность типов
- •Совместимость типов
- •Совместимость по присваиванию
- •Преобразование типов
- •Операторы обработки исключительных ситуаций
- •Пример 11
- •Множества
- •Операции над множествами
- •Пример 12
- •Вариантный тип данных
- •Процедуры и функции
- •Процедура
- •Функция
- •Рекурсия
- •Формальные и фактические параметры
- •Параметры-значения
- •Параметры-переменные
- •Параметры-константы
- •Параметры без типа
- •Массивы открытого типа
- •Парамеры по умолчанию
- •Процедура exit
- •Директивы подпрограммы
- •Соглашения по передаче данных
- •Директива forward
- •Директива external
- •Директива assembler
- •Перегруженные подпрограммы
- •Пример 13
- •Инкапсуляция
- •Класс как объектный тип
- •Наследование
- •Области видимости
- •Операции is и as
- •Виды методов
- •Методы virtual и полиморфизм
- •Методы dynamic
- •Методы message
- •Методы abstract
- •Методы override
- •Методы class
- •Пример 14
- •Динамическое создание компонентов
- •Использование класса со счетчиком объектов
- •Отслеживание разрушения объектов
- •События
- •Указатели на методы
- •Пример 15
- •Типы ссылки на класс
- •Свойства
- •Свойства simple
- •Свойства enumerated
- •Свойства set
- •Свойства object
- •Свойства array
- •Задание начальных значений свойствам
- •Пример 16
- •Файловые типы
- •Текстовые файлы
- •Типизированные файлы
- •Файлы без типа
- •Дополнительные процедуры и функции
- •Пример 17
- •Компонент tmainmenu
- •Указатели
- •Пример 18
- •Динамические структуры данных
- •Однонаправленные списки
- •Двунаправленные списки
- •Стеки, очереди
- •Бинарные деревья
- •Пример 19
- •Процедурный тип
- •Программные единицы dll
- •Пример 20
- •Технологии программирования
- •Потоки данных
- •Пример 21
- •Пример 22
- •Интерфейс drag and drop
- •Пример 23
- •Технология drag and dock
- •Пример 24
- •Использование функций windows api при работе с файлами
- •Пример 25
- •Использование отображаемых файлов
- •Пример 26
- •Программные потоки
- •Приоритеты потоков
- •Класс tthread
- •Пример 27
- •Использование блокировки в примере 27
- •Многопоточное приложение в примере 28
- •Проблемы синхронизации потоков
- •Список используемых в примерах компонентов
- •Список используемых компонентов и других классов
- •Библиографический список
- •Оглавление
Класс tthread
Для реализации потоков Delphi предоставляет класс TThread. Наиболее важными методами являются Execute и Synchronize. Первый метод осуществляет выполнение потока. Этот метод абстрактный. Поэтому необходимо создать класс, который является потомком TThread, и в этом классе переопределить метод Execute. Второй метод Synchronize, чтобы избежать одновременного использования компонентов приложения, сообщает основной подзадаче, что требуется обращение к ресурсам, которые, возможно, заняты. При этом передается адрес метода, который основная подзадача может вызвать, чтобы выполнить требуемую потоком работу. Процесс извещения является последовательным и основная подзадача должна полностью завершить выполняемую работу, прежде чем получить следующее извещение. Извещающее сообщение отсылается при помощи подпрограммы Windows SendMessage. Результатом является то, что подзадача будет заморожена вплоть до полной отработки задания внутри основной подзадачи.
В программе перед выполнением потока, являющегося классом, естественно, должен быть построен соответствующий объект. Для этого вызывается метод Create, имеющий один аргумент CreateSuspended типа Boolean. Если поток создан со значением аргумента CreateSuspended = false, то он немедленно (как только получит время процессора в соответствии с его собственным приоритетом и приоритетом процесса) начинает выполняться (запускается метод Execute), в противном случае Execute запускается вызовом метода Resume. Внутри метода Execute могут выполняться некоторые циклические действия, для завершения которых можно воспользоваться свойством Terminated. Устанавливая значение этого свойства равным true или внутри метода Execute или извне, поток получает команду о завершении его работы. С помощью метода Suspend можно приостановить работу потока и затем продолжить, вызывая метод Resume. Переустанавливая значение свойства Priority, можно управлять приоритетом потока.
Пример 27
Рассмотрим простой пример по использованию одного дополнительного потока. Пусть некоторый поток с помощью собственного метода, например, Paint применяется для закраски некоторой области прямоугольной формы. Основной поток приложения создается для рисования окружностей внутри той же области с помощью обработчика OnMouseDown.
Для построения приложения необходимо создать проект с двумя модулями. Один модуль – основная программа с объявленной переменной типа поток в секции Public внутри создавемого класса формы, другой модуль – модуль потока. Поместим на форму две кнопки TButton. Создадим для них два обработчика OnClick. Для формы, как уже отмечено, создается обработчик OnMouseDown. Далее создадим модуль для реализации вспомогательного потока (основной поток автоматически создается для процесса (приложения)).
Необходимо открыть меню File - New и выбрать пункт Other. Откроется диалоговое окно, в котором нужно выбрать (дважды щелкнуть мышкой) значок Thread Object. Когда появится диалоговое окно для именования объекта поток, необходимо ввести имя класса TThread (Class Name = TPaintThread) и нажать на кнопку OK. Ниже приводится весь программный код данного примера, который демонстрирует использование метода Synchronize.
unit MyThread1; {Модуль для определения потока}
interface
uses Classes;
type
TPaintThread = class(TThread)
private
x,y:integer;
protected
procedure Execute; override;
procedure Paint;
end;
implementation
uses Unit27_1, Graphics;
procedure TPaintThread.Execute;
begin
randomize;
Repeat
x:=random(250);
y:=random(Form1.ClientHeight);
Synchronize(Paint);
until Terminated;
end;
procedure TPaintThread.Paint;
begin
Form1.Canvas.Pixels[x,y]:=clPurple;
end;
end.
unit Unit27_1; {Основной модуль}
interface
uses
Windows, Messages, SysUtils, Variants, Classes,
Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, Buttons, MyThread1;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
BitBtn1: TBitBtn;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormMouseDown(Sender: TObject; Button:
TMouseButton; Shift: TShiftState; X, Y: Integer);
public
MyPaintThread:TPaintThread;
end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Button1.Enabled:=false;
Button2.Enabled:=true;
MyPaintThread:=TPaintThread.Create(false);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
MyPaintThread.Free;
Button1.Enabled := True;
Button2.Enabled := False;
end;
procedure TForm1.FormMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
Canvas.Pen.Color := Color;
Canvas.Brush.Color := Color;
Canvas.Ellipse (x - 30, y - 30, x + 30, y + 30);
end;
end.
Следует обратить внимание на строку MyPaintThread:TPaintThread; и использование модуля Graphics. Среда Delphi может не добавить этот модуль в список Uses. На рис. 63 приводится вариант решения данного примера.
Рис. 63. Вариант решения примера 27.