Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лаб_раб3.Разработка многопоточных задач в среде....doc
Скачиваний:
3
Добавлен:
10.07.2019
Размер:
84.48 Кб
Скачать

Разработка многопоточных задач в среде delphi

Многопоточность используется для: - обхода медленных процессов. Когда используется только один поток, приложение может приостановить свое выполнение на то время, пока им завершается какой-либо медленный процесс (доступ к диску, связь с другим компьютером по сети и т. д.). Центральный процессор компьютера в данный момент находится в режиме ожидания и практически не выполняет никаких команд. С использованием многопоточности приложение может продолжать выполнение других потоков, пока один из потоков ожидает завершение медленного процесса; - организации поведения приложения. Благодаря использованию потоков, можно для каждой задачи приложения (если каждой задаче выделен свой поток) распределить приоритеты выполнения. Задача, имеющая наибольший приоритет, будет занимать больше процессорного времени, что очень важно для решения критических задач; - поддержки мультипроцессорной обработки. Если в компьютере, на котором запущено многопоточное приложение, имеется несколько процессоров, то можно значительно увеличить скорость выполнения приложения, направляя на каждый процессор свой поток.

  • Процесс — это понятие, относящееся к операционной системе. Каждый раз, когда запускается приложение, система создает и запускает новый процесс.

  • Поток (Thread) - это объект операционной системы, заключенный в процесс и реализующий какую-либо задачу.

  • Каждый процесс обязательно создает первичный поток (primary thread) выполнения

  • Класс TThread является прямым потомком объекта TObject, следовательно, он не является визуальным компонентом.

  • Объект TThread является абстрактным, поэтому нельзя создать экземпляр этого класса

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

  • При создании многопоточных приложений необходимо: - не создавать слишком много потоков - это может привести к большой загруженности операционной системы и процессора. Рекомендуемое ограничение числа активных потоков в одном процессе - 16 (для однопроцессорной системы); - использовать синхронизацию в случае, когда несколько потоков пытаются получить доступ к одному ресурсу;

Пример создания многопоточного приложения в Delphi

Задача: создать простое приложение, состоящее из трех потоков.

  1. В главном меню выбрать пункт File/New Application.

  2. Р

    азместить на главной форме приложения поле для редактирования Edit (закладка Standard), индикатор хода выполнения работы Progress Bar (закладка Win32) и системный таймер Timer (закладка System).

  1. Добавить новый объект потока через пункт главного меню Delphi File/New/Other->Thread Object. В открывшемся диалоговом окне ввести имя для нового потомка класса TThread, например TmyThread1. Delphi автоматически добавит модуль Unit2 в приложение.В этом модуле появится заготовка

unit Unit2;

interface

uses

Classes;

type

TMyThread1 = class(TThread)

private

{ Private declarations }

protected

procedure Execute; override; //метод класса абстрактный,поэтому override

end;

implementation

{ TMyThread1 }

procedure TMyThread1.Execute;

begin

{ Place thread code here }

end;

end.

  1. В раздел public добавить глобальную переменную count. В результате должно получиться следующее:

type

TMyThread1 = class(TThread)

private

{ Private declarations }

protected

procedure Execute; override;

public // добавлено

count:integer; // добавлено

end;

  1. Записать в метод Execute код, который должен выполняться в потоке. Пусть это будет код, который генерирует случайные числа и присваивает их глобальной переменной count. Для того чтобы генерация случайных чисел была бесконечной, зациклим ее с помощью так называемого "бесконечного цикла":

procedure TMyThreadl.Execute; begin while true do begin count:=random(maxint); end; end;

  1. Создать второй объект потока, который должен заполнять индикатор хода работы (Progress Bar). По аналогии с первым объектом потока, при помощи главного меню Delphi создать объект потока с именем TMyThread2. Во вновь добавленном модуле Unit3 определить глобальную переменную prcount:

type TMyThread2 = class(TThread) private { Private declarations } protected procedure Execute; override; public // добавлено prcount:integer; // добавлено end;

  1. В процедуре Execute объекта TMyThread2 записать следующий код, также зациклив его:

procedure TMyThread2.Execute; begin

while true do begin prcount:=prcount+l; if prcount>100 then prcount:=0; end; end;

  1. Сохранить проект Project1 и модули Unit1, Unit2, Unit3.

  2. Добавить в модуле Unit1 в описание класса формы в разделе private объекты потоков Thread1 - потомок класса TmyThreadl1и Thread2 - потомок класса TMyThread2:

type TForml = class(TForm) ProgressBarl: TProgressBar; Editl: TEdit; Timerl: TTimer; procedure FormCreate(Sender: TObject); private Threadl:TMyThreadl; // добавлено Thread2:TMyThread2; // добавлено public { Public declarations } end;

  1. Дважды щелкнуть на любом свободном пространстве формы Form1. При этом откроется "заготовка" для метода создания формы FormCreate формы Form1. В обработчике FormCreate ввести код:

procedure TForml.FormCreate(Sender: TObject); begin Thread1:=TmyThread1.Create(False); // конструктор Thread1.priority:=tpLowest; // установка приоритета потока (см. ниже) Thread2:=TMyThread2.Create(False); // конструктор Thread2.priority:=tpNormal; // установка приоритета потока end;

Параметр, который передается в методе Create класса TThread- CreateSuspended. Данный параметр может принимать логическое значение истина или ложь (true, false). Этот параметр показывает, создавать поток в приостановленном состоянии (true) или запускать его сразу же (false). То есть метод Execute будет вызван автоматически сразу, если параметр CreateSuspended равен false.

Приоритеты указывают операционной системе, сколько процессорного времени выделяется для данного потока. Для критических задач можно установить наивысший приоритет, для менее значимых - более низкий приоритет. Приоритет каждого потока складывается из двух составляющих:

-класса приоритета - приоритета процесса, породившего поток;

- относительного приоритета - приоритета самого потока. Класс приоритета процесса может принимать одно из четырех значений: Idle, Normal, High и Realtime, которые выражаются числовыми значениями от 4 до 24. По умолчанию, любое приложение получает приоритет Normal. Процессов (в примере используется этот приоритет).

Классы приоритетов процессов

Значение класса

Приоритет

Числовое значение

Idle

Низший приоритет для выполнения фоновых задач

4

Normal

Стандартный приоритет, который имеют большинство приложений Windows

7-9

High

Приоритет высокого уровня, приложение получает больше процессорного времени, чем имеющее класс Normal

13

Realtime

Наивысший уровень приоритета

24

Для определения текущего и установки требуемого класса приоритета используются функции GetPrioriryClass и SetPriorityClass соответственно. Для установки высокого класса приоритета (High) можно, например, использовать следующий код: If not SetPriorityClass(GetCurrentProcess, HIGH_PRIORITY_CLASS) then ShowMessage ('Ошибка установки класса приоритета'); По возможности следует избегать установки классов приоритетов High и Realtime, т. к. поток приложения может получить больше процессорного времени, чем сама операционная система, что может привести к серьезным проблемам. Для установки значения относительного приоритета у потоков имеется свойство Priority, которое может принимать семь значений.