- •ПРОЦЕСС И ПОТОК
- ••Процесс - экземпляр выполняемого приложения. При запуске приложения происходит выделение памяти под процесс,
- ••Каждый поток может создать другой поток и т.д.
- ••В 32-х разрядных версиях Windows используется вытесняющая многозадачность
- •Класс – TThread
- •Запустить поток
- •Пример
- •Назовем свой поток tnew
- ••У объекта есть только одна процедура Execute. В любых потоках эта процедура обязана
- ••procedure TCountObj.Execute;
- •Переменную index объявим как integer в разделе private объекта потока. Там же объявим
- ••подключаем главную форму в раздел uses. В методе Execute запускается цикл while, который
- •офункции Synchronize.
- •Главная программа
- ••В разделе private объявляем переменную co типа Ttnew (объект нашего потока). По нажатию
- •возможности потоков
- ••Suspended - если этот параметр true, то поток находится в паузе.
- •сообщение SendMessage
- •сообщение SendMessage
- ••const
- •Критические секции
- ••У TCriticalSection есть два нужных нам метода, Enter и Leave, соответственно вход и
Переменную index объявим как integer в разделе private объекта потока. Там же объявим процедуру UpdateLabel. Эта
процедура выглядит так: procedure TCountObj.UpdateLabel; begin
Form1.Label1.Caption:=IntToStr(Index);
end;
•подключаем главную форму в раздел uses. В методе Execute запускается цикл while, который будет выполняться, пока переменная index больше нуля.
Внутри цикла вызывается метод Synchronize увеличивается переменная index.
офункции Synchronize.
•Если процедура вызвана в методе Synchronize, то выполнение основной программы и потока замораживается и
ккомпонентам окна получает доступ
только объект, вызвавший метод
Synchronize.
Главная программа
•В раздел uses главной формы (самый первый, который идёт после interface) добавяемл модуль потока MyThread.
Это связано с тем, что в разделе private нужно объявить переменную имеющую
тип нашего объекта. Если добавить имя модуля во второй раздел uses, то он
находиться ниже той части кода, где
нужно написать объявление. Именно поэтому добавлять модуль MyThread
нужно в первый раздел uses.
•В разделе private объявляем переменную co типа Ttnew (объект нашего потока). По нажатию кнопки "Запустить" напишем такой код:
•procedure TForm1.Button1Click(Sender: TObject);
•begin
•co:=Ttnew.Create(true);
•co.Resume;
•co.Priority:=tpLower;
•end;
возможности потоков
•Suspend - приостанавливает поток. Для вызова нужно написать co.Suspend. Чтобы возобновить работу с этой же точки нужно вызвать Resume.
•Priority- устанавливает приоритет потока. Например Priority:=tpIdle;
•tpIdle - поток будет работать только когда процессор бездельничает.
•tpLowest - самый слабый приоритет
•tpLower - слабый приоритет
•tpNormal - нормальный
•tpHigher - высокий
•tpHighest - самый высокий
•tpTimeCritical - критичный.
•Suspended - если этот параметр true, то поток находится в паузе.
•Terminated - если true, то поток должен быть остановлен, иначе поток должен продолжать работу.
•Terminate – остановить выполнение потока.
•FreeOnTerminate – если это свойство равно true, то по завершении выполнения процедуры Execute поток самоуничтожиться.
сообщение SendMessage
•Каждый раз, когда надо обновить
содержимое текста мы можем посылать окну сообщение SendMessage с указанием значения, которое надо установить. Главное окно будет получать это сообщение и компонент сам изменит заголовок. В этом случае мы не обращаемся к главному окну из потока, а только отправляем сообщение.
сообщение SendMessage
SendMessage(Form1.Edit1.Handle, WM_SETTEXT, 0, Integer(PChar(IntToStr(index))));
в разделе uses нужно добавить два модуля: windows (здесь объявлена сама функция) и messages (здесь находятся все типы сообщений Windows).
•const
PROGRESS_POS = WM_USER+1;
В объявление класса формы добавим новый метод, а затем и его реализацию:
TForm1 = class(TForm) Button1: TButton; ProgressBar1: TProgressBar;
procedure Button1Click(Sender: TObject); private
procedure SetProgressPos(var Msg: TMessage); message PROGRESS_POS; public
{ Public declarations } end;
...
procedure TForm1.SetProgressPos(var Msg: TMessage); begin
ProgressBar1.Position:=Msg.LParam;
end;
Теперь мы немного изменим, можно сказать даже упростим, реализацию метода Execute нашего потока:
procedure TNewThread.Execute; var
i: integer; begin
for i:=0 to 100 do begin
sleep(50); SendMessage(Form1.Handle,PROGRESS_POS,0,i); end;
end;
•TNewThread = class(TThread) private
{ Private declarations } protected
procedure Execute; override;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TNewThread }
procedure TNewThread.Execute; begin
while true do {ничего не делаем}; end;
procedure TForm1.Button1Click(Sender: TObject); var
NewThread: TNewThread; begin
NewThread:=TNewThread.Create(true);
NewThread.FreeOnTerminate:=true;
NewThread.Priority:=tpLower;
NewThread.Resume;
end;