Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
21 ошибка прогр... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
ТЕХНОЛОГИИ ДОСТ... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Имитационное мо... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Реклама
Сейчас на сайте
Гостей: 48
На сайте нет зарегистрированных пользователей

Пользователей: 13,361
новичок: uehuat
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Моделирование ЭВМ на GPSS (три класса заданий) + Пояснительная записка
Выбор наилучших альтернатив с использованием методов оптимизации на Delp...
Обработка задач на ЭВМ на GPSS + Пояснительная записка

Создание потоков средствами класса TThread
Среда программирования Delphi предоставляет программисту доступ к возможностям создания многопоточных приложений с помощью специального класса TThread.
С точки зрения операционной системы (ОС) потокэто ее объект. При создании он получает дескриптор и отслеживается ОС. Объект класса TThread – это конструкция Delphi, соответствующая потоку. Этот объект создается до реального возникновения потока в системе и уничтожается после его исчезновения. Другая отличительная черта класса TThread – это совместимость с библиотекой визуальных компонентов VCL.
Класс TThread включает в себя следующие элементы:
1. Constructor Create (Create Suspended: Boolean);
В качестве аргумента он получает параметр CreateSuspended. Если его зна¬чение равно True, вновь созданный поток не начинает выполняться до тех пор, пока не будет сделан вызов метода Resume. В случае, если CreateSuspended имеет значение False, поток начинает исполнение и конструктор завершается.
2. Destructor Destroy; override;
Деструктор Destroy вызывается, когда необходимость в созданном потоке отпадает. Деструктор завершает его и высвобождает все ресурсы, связанные с объектом TThread.
3. Procedure Resume;
Метод Resume класса TThread вызывается, когда поток возобновляется после остановки, или если он был создан с параметром create Suspended, равным True.
4. Procedure Suspend;
Вызов метода Suspend приостанавливает поток с возможностью повторного запуска впоследствии. Метод Suspend приостанавливает поток вне зависимости от кода, исполняемого потоком в данный момент; выполнение продолжается с точки останова.
5. Property Suspended: Boolean;
Свойство Suspended позволяет программисту определить, не приостановлен ли поток. С помощью этого свойства можно также запускать и останавливать поток. Установив suspended в True, будет получен тот же результат, что и при вызове метода Suspend — приостановку. Наоборот, установка Suspended в False возобновляет выполнение потока, как и вызов метода Resume.
6. Function Terminate: Integer;
Метод Terminate существует для окончательного завершения потока (без последующего запуска). Он останавливает поток и возвращает управление вызвавшему процессу только после того, как это произошло. Значение, возвращаемое функцией Terminate, соответствует состоянию потока. Примерами возможных состояний являются случай нормального завершения и случай, когда к моменту вызова Terminate поток уже завершился (или был завершен из другого потока) .
7. Property Terminated: Boolean;
Свойство Terminated позволяет узнать, произошел ли уже вызов метода Terminate или нет.
8. Function WaitFor: Integer;
Метод WaitFor предназначен для синхронизации потоков и позволяет одному потоку дождаться момента, когда завершится другой поток. Если внутри потока FirstThread имеется код:
Code := SecondThread.WaitFor;



то это означает, что поток FirstThread останавливается до момента завершения потока SecondThread. Метод WaitFor возвращает код завершения ожидаемого потока.
9. Property Handle: THandle read FHandle;
Property ThreadID: THandle read FThreadID;

Свойства Handle и ThreadID дают программисту непосредственный доступ к потоку средствами API Win 32. Если необходимо обратиться к потоку и управлять им, минуя возможности класса TThread, значения Handle и ThreadID могут быть использованы в качестве аргументов функций Win 32 API. Например, если перед продолжением выполнения приложения необходимо дождаться завершения сразу нескольких потоков, то следует вызвать функцию API WaitForMuitipleObjects. Для ее вызова необходим массив дескрипторов потоков.
10. Property Priority: TThreadPriority;
Свойство Priority позволяет запросить и установить приоритет потоков. Приоритет определяет, насколько часто поток получает время процессора. Допустимыми значениями приоритета являются tpIdie, tpLowest, tpLower, tpNormal, tpHigher, tpHighest и tpTimeCritical.
11. Procedure Synchronize (Method: TThreadMethod);
Этот метод относится к секции protected, то есть может быть вызван только из потомков TThread. Delphi предоставляет программисту метод synchronize для безопасного вызова методов VCL внутри потоков. Во избежание ситуаций гонок , метод synchronize дает гарантию, что к каждому объекту VCL одновременно имеет доступ только один поток. Аргумент, передаваемый в метод synchronize, — это имя метода, который производит обращение к VCL. Вызов Synchronize с этим параметром — это то же, что и вызов самого метода. Такой метод (класса TThreadMethod) не должен иметь никаких параметров и не должен возвращать никаких значений. Например, в основной форме приложения нужно предусмотреть функцию
procedure TMainForm.SyncShowMessage;
begin
ShowMessage(IntToStr(Listl.Count));
//другие обращения к VCL
end;



Тогда в потоке для показа сообщения следует писать не
ShowMessage(IntToStr(Listl.Count));



и даже не
MainForm.SyncShowMessage;



а только следующим образом:
Synchronize(MainForm.SyncShowMessage);



Производя любое обращение к объекту VCL из потока, следует убедиться, что при этом используется метод Synchronize; в противном случае результаты могут оказаться непредсказуемыми.
12. Procedure Execute; virtual; abstract;
Эта процедура является главным методом объекта TThread. В теле метода должен содержаться код, который представляет собой программу потока. Метод Execute класса TThread объявлен как абстрактный.
Переопределяя метод Execute, можно тем самым закладывать в новый потоковый класс то, что будет выполняться при его запуске. Если поток был создан с аргументом CreateSuspended, равным False, то метод Execute выполняется немедленно, в противном случае Execute выполняется после вызова метода Resume.
Если поток рассчитан на однократное выполнение каких-либо действий, то никакого специального кода завершения для него писать не надо. После выполнения метода Execute будет вызван деструктор, который сделает все необходимое.
Если же в потоке будет выполняться какой-то цикл, и поток должен завершиться вместе с приложением, то условия окончания цикла должны быть примерно такими:
procedure TMyThread.Execute;
begin
repeat
DoSomething;
until CancelCondition or Terminated end;



Здесь CancelCondition — условие завершения потока пользователя (исчерпание данных, поступление на вход того или иного символа и т. п.), а свойство Terminated говорит о завершении потока извне (скорее всего, завершается породивший его процесс).
С завершением потока следует быть очень внимательным, — если он зациклился и не реагирует на сигналы завершения, то зависнет все приложение.
13. Property ReturnValue: Integer;
Свойство ReturnValue позволяет узнать и установить значение, возвращаемое потоком по его завершении. Эта величина полностью определяется пользователем. По умолчанию поток возвращает ноль, но если программист захочет вернуть другую величину, то простое изменение свойства ReturnValue внутри потока позволит получить эту информацию другим потокам. Это, например, может пригодиться, если внутри потока в ходе его выполнения возникла какая-либо сложная ситуация.

Рассмотрим примеры создания простых многопоточных приложений.
П р и м е р 2. Создается приложение, выполняющее те же операции, что и в примере1.
Для создания приложения выполниту следующие действия:
1. Разместите на форме две строки редактирования, два регулятора и один компонент типа TTimer, как показано на рис. 2.
Создание потоков средствами класса TThread
Рис. 2
2. Выполните команду File | Save Project As и сохраните модуль и проект, назначив им соответствующие имена.
3. Выполните команду File | New | Other. В открывшемся диалоговом окне New Items выполните двойной щелчок на объекте типа поток (значок Thread Object).
4. В диалоговом окне для именования объекта поток (рис. 3) введите TSimpleThread и нажмите ОК.

Рис. 3
Delphi создаст шаблон для нового потока, который показан далее:
unit Unitl;
interface
uses
Classes;
type
TSimpleThread= class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
end;
implementation
{Важно: методы и свойства объектов из состава VCL могут быть использованы посредством метода под названием Synchronize, например, Synchronize(UpdateCaption), где UpdateCaption может выглядеть так:
procedure TSimpleThread. UpdateCaption;
begin
Form. Caption: 'Updated in a thread';
end; }
( TSimpleThread }
procedure TSimpleThread. Execute;
Var
begin
{ Код потока помещается здесь }
end;
end. }



5. Измените объявление класса TSimpleThread, чтобы включить в секцию public поле Count. Поле count будет использовано, чтобы подсчитать, сколько вычислений в секунду выполняется в потоке:
TSimpleThread = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
public
Count: Integer;
end;



6. Изменения, вносимые в модуль Execute, как и в примере 1, заключаются в том, чтобы подсчитать среднее значение десяти случайных чисел и затем увеличить на единицу значение count. Эти изменения показаны ниже:
procedure TSimpleThread.Execute;
Var
I, Total, Avg: Integer;
begin
While True Do
Begin
Total: =0;
For I:=1 To 10 Do
Inc(Total, Random(MaxInt));
Avg:=Avg Div 10;
Inc(Count );
End;
end;



7. Выполните команду File | Save As… и сохраните модуль с потоком как Thrd.pas.
8. Отредактируйте главный файл модуля и добавите модуль Thrd к списку используемых модулей. Он должен выглядеть так:
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Thrd, ExtCtrls, StdCtrls, ComCtrls;



9. В секции public формы TForm1 добавьте следующую строку:
Thread1, Thread2: TSimpleThread;



10. Выполните двойной щелчок на свободном месте рабочей области формы, чтобы объявить два потока, которые будут использоваться программой; при этом создастся шаблон метода FormCreate. В этом методе произойдет создание потоков, присвоение им приоритетов и запуск. Поместите в шаблон FormCreate следующий код:
procedure TForm1.FormCreate(Sender: TObject);
begin
Thread1:=TSimpleThread.Create(False);
Thread1.Priority:=tpLowest;
Thread2:=TSimpleThread.Create(False);
Thread2.Priority:= tpLowest;
end;



11. Выполните двойной щелчок на компоненте TTimer для создания пустого шаблона метода Timer. Этот метод будет автоматически вызываться каждую секунду, чтобы приложение могло отслеживать состояние потоков. Метод Timer должен выглядеть следующим образом:
procedure TForm1.Timer1Timer (Sender: TObject);
begin
Edit1.Text:=IntToStr(Thread1.Count );
Edit2.Text:=IntToStr(Thread2.Count );
Thread1.Count: =0;
Thread2. Count:=0;
end;



12. Выполните щелчок на левом регуляторе (TrackBar1) и выберите страницу Events в окне Object Inspector. Выполните двойной щелчок напротив имени метода OnChange для создания шаблона метода, который будет вызываться каждый раз при изменении положения регулятора. Метод будет устанавливать регулятор в соответствии с приоритетом потока. Он должен содержать следующий код:
procedure TForm1.TrackBar1Change (Sender:TObject);
Var
I: Integer;
Priority: TThreadPriority;
begin
Priority:=tpLowest;
For I: = 0 To (Sender as tTrackBar).Position - 1 Do
inc(Priority);
if Sender = TrackBar1
Then Thread1.Priority:=Priority
Else Thread2.Priority:=Priority;
end;



13. Чтобы связать метод, созданный на шаге 12, со вторым регулятором, следует выбрать в окне Object Inspector TrackBar2, открыть комбинированный список события OnChange и выбрать метод TrackBar1Change.
14. Чтобы ограничить приоритет потоков, значением не выше, чем tpHigher, максимальное положение регуляторов должно быть ограничено четырьмя. Для этого выберите TrackBar1, и затем, удерживая клавишу , выберите TrackBar2. Когда оба компонента будут выделены, откройте в окне Object Inspector страницу Properties и установите для свойства Max значение 4.
15. Запустите подготовленное приложение на выполнение. Изменяя приоритеты, проанализируйте их влияние на производительность одновременно выполняющихся потоков.


Сноски:
1 Метод Terminate автоматически вызывается и из деструктора объекта. В явном виде его за редким исключением, вызывать не надо.
2 Следует с осторожностью использовать приоритеты tpHighest и tpTimeCritical. Оба они могут оказать влияние на выполнение приложения, а последний — и на всю операционную систему.
3 Ситуация гонок возникает, когда два или более потока пытаются получить доступ к общему ресурсу и изменить его состояние.






Опубликовал Kest January 01 2010 18:57:54 · 0 Комментариев · 30959 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
Нет комментариев.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
PHP 5. Полное рук...
Технология .Net в VB
Image Browser [Ис...
45 уроков по дельфи
Открытие Cd-ROM'a...
Язык программиров...
Х. М. Дейтел, П. ...
PBEditPack
Exe in exe
Доступа к БД Fire...
ATComponents
Измерение тактово...
Bitmap [для кнопок]
FormShape [Исходн...
TsHintManager
Фундаментальные а...
DirHTMLReportBuil...
Swat [Исходник на...
Панель поиска
Трассировка прово...

Топ загрузок
Приложение Клие... 100772
Delphi 7 Enterp... 97809
Converter AMR<-... 20261
GPSS World Stud... 17014
Borland C++Buil... 14189
Borland Delphi ... 10267
Turbo Pascal fo... 7372
Калькулятор [Ис... 5972
Visual Studio 2... 5206
Microsoft SQL S... 3661
Случайные статьи
Большая Н из отрез...
Клиенты Windows fo...
Теги Alt и Title в...
Межмодульные перем...
Размещение элемент...
Группа блоков созд...
Создание документа...
ЭТИКА РАЗРАБОТКИ П...
Структура наследов...
Изменение собствен...
Оптимизация работы...
Элементы applet и ...
Простой графически...
Основные параметры...
Генерирование сигн...
Инфографика со сра...
Как зарегистрирова...
Ремонт телефонов П...
Возможность подклю...
Глава 6. Обучен...
Класс TPaintBox
Риски безопасности...
Непосредственная а...
пользователей,ш; с...
BestChange.ru – са...
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?