Среда, 15.05.2024
Королевство Delphi
Главное меню
Статьи
Наш опрос
Нужен форум на сайте?
Всего ответов: 90
Статистика
Онлайн всего: 1
Гостей: 1
Пользователей: 0
Форма входа
Главная » Статьи » Система » Разное

Потоки

Сегодня нам предстоит познакомится с потоками. Эта штука очень интересная и беспощадно нужная. Всё программирование звука будет написано с использованием потоков, так что вникай где суть.

Представь, что ты хочешь вставить в свою прогу проверку орфографии. Если ты после каждой нажатой клавиши будешь проверять правильность слов, то твоя прога будет сумасшедше тормозить. А как же это делает MS Word ? Очень просто, после запуска проги запускается поток, который в фоновом режиме производит проверку орфографии. Ты спокойно набираешь текст и даже не ощущаешь (почти) как параллельный процесс в свободное время производит сложнейшие проверки твоих каракуль.

Любая программа содержит хотя бы один поток (главный), в котором она выполняется. Помимо этого, она может порождать любое количество дополнительных потоков, которые будут выполняться в фоновом режиме. У дополнительных потоков приоритет выставляется такой же как и у главного потока программы, но ты его можешь увеличить или уменьшить. Чем выше приоритет потока, тем больше на него отводится процессорного времени.

Да что тут распинаться, давай программировать. Со всем разберёмся в процессе.

Создай новый проект. Поставь на форму ТRichEdit из палитры Win32 и один TLabel. Это мы создали форму, а теперь создадим поток.

Выбери File -> New (рисунок 1). Находишь там Thread Object , выделяешь и щёлкаешь "ОК". Появляется окошко, как на рисунке 2. Вводим имя потока (я ввёл TCountObj).

Сохраняем весь проект. Главную форму под именем main (как всегда), а поток под именем MyThread.

После этого Delphi создаст вот такой код:

unit MyThread;

interface

uses
 Classes;

type
 TCountObj = class(TThread)
 private
 { Private declarations }
 protected
 procedure Execute; override;
 end;

implementation

{ Important: Methods and properties of objects in VCL can only be used in a
 method called using Synchronize, for example,

 Synchronize(UpdateCaption);

 and UpdateCaption could look like,

 procedure TCountObj.UpdateCaption;
 begin
 Form1.Caption := 'Updated in a thread';
 end; }

{ TCountObj }

procedure TCountObj.Execute;
begin
 { Place thread code here }
end;

end.

Это новый поток. У объекта есть только одна функция Execute . В этой функции мы и будем писать код потока. Напишем вот что:

procedure TCountObj.Execute;
begin
 index:=1;
 //Запускаем бесконечный счётчик
 while index>0 do
 begin
 Synchronize(UpdateLabel);
 Inc(index);
 if index>100000 then
 index:=0;

 //Если поток остановлен, то выйти.
 if terminated then exit; 
 end;
end;

index я объявил как integer в разделе private потока. Там же я объявил процедуру UpdateLabel. Эта процедура выглядит так:

procedure TCountObj.UpdateLabel;
begin
 Form1.Label1.Caption:=IntToStr(Index);
end;

И последнее, что я сделал - подключил главную форму в раздел uses, потому что я обращаюсь к ней в коде выше (Form1.Label1.Caption).

Теперь о магической функции Synchronize. В качестве параметра ей передаётся процедура UpdateLabel, которая производит вывод в главную форму. Для чего нужно вставлять вывод на экран в Synchronize? Библиотека VCL имеет один косяк - она не защищена от потоков. Если главная форма и поток попробуют одновременно вывести что-нибудь в одну и ту же область экрана или компонент, то программа рухнет как эфелева башня. Поэтому весь вывод на форму нужно выделять в отдельную процедуру и вызывать эту процедуру с помощью Synchronize.

Что происходит во время вызова Synchronize? В этот момент поток останавливается и управление передаётся главному потоку, который и произведёт обновление.

Наш поток готов. Возвращаемся к главной форме. Я её сделал, как на рис 3. В раздел uses (самый первый, который идёт после interface) я добавил свой поток MyThread.

В разделе private я объявил переменную co типа TCountObj (объект моего потока).

По нажатию кнопки "Запустить" я написал такой код:

procedure TForm1.Button1Click(Sender: TObject);
begin
 co:=TCountObj.Create(true);
 co.Resume;
 co.Priority:=tpLower;
end;

В первой строке я создаю поток co. В качестве параметра может быть true или false. Если false, то поток сразу начинает выполнение, иначе поток создаётся, но не запускается. Для запуска нужно использовать Resume, что я делаю во второй строке.

В третьей строке я устанавливаю приоритет потока поменьше, чтобы он не мешал работе основному потоку и выполнялся в фоне. Если установить приоритет повыше, то основной поток начнёт притормаживать, потому что у них будут одинаковые приоритеты.

По кнопке "Остановить" я написал:

procedure TForm1.Button1Click(Sender: TObject);
begin
 co.Terminate;
 co.Free;
end;

В первой строке я останавливаю выполнение потока, а во второй уничтожаю его.

Попробуй запустить прогу, запустить поток (нажатием кнопки "Запустить") и понабирать текст в RichEdit. Текст будет набиратся без проблем, и в это время в ТLabel будет работать счётчик. Если бы ты запустил счётчик без отдельного потока, то ты бы не смог набирать текст в RichEdit, потому что все ресурсы программы (основного потока) уходили бы на работу счётчика.

Итак, наш первый поток готов. При программировании звука мы напишем более полезные примеры с потоками. А сейчас ещё несколько полезных фишек:

  • Suspend - приостанавливает поток. Для вызова просто напиши co.Suspend. Чтобы возобновить работу с этой же точки нужно вызвать Resume.
  • Priority- устанавливает приоритет потока. Например Priority:=tpIdle;
    • tpIdle - поток будет работать только когда процессор бездельничает.
    • tpLowest - самый слабый приоритет
    • tpLower - слабый приоритет
    • tpNormal - нормальный
    • tpHigher - высокий
    • tpHighest - самый высокий
    • tpTimeCritical - критичный (не советую использовать, потому что может грохнуть систему).
  • Suspended - если этот параметр true, то поток находится в паузе.
  • Terminated - если true, то поток должен быть остановлен.

Вот и всё. С потоками окончено.

Получить ссылку на материал

Категория: Разное | Добавил: Барон (20.12.2011)
Просмотров: 1369 | Теги: потоки | Рейтинг: 0.0/0
[ Пожертвования для сайта ] [ Пожаловаться на материал ]

Если вам помог материал сайта кликните по оплаченной рекламе размещенной в центре

Поиск
Категории раздела
ActiveX [10]
CORBA и COM [16]
Kol и MCK [23]
WinAPI [28]
Компоненты [27]
Работа с Bluetooth [4]
Железо [8]
Текст [18]
Разное [98]
Королевство Delphi © 2010-2024
Яндекс цитирования