На этом шаге мы рассмотрим приложение,
в котором демонстрируется работа потоков с разными приоритетами.
На форму следует поместить шесть компонетнов TLabel и два компонента TButton. Вид формы представлен на рис. 1.

Рис.1. Вид формы приложения
Проект содержит два модуля. Текст модуля Main.
unit Main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, MyThread;
type
TForm1 = class(TForm)
Label1: TLabel;
Button1: TButton;
Button2: TButton;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
co1:TCountObj1;
co2:TCountObj2;
co3:TCountObj3;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin
//создаем объекты потоков
co1:=TCountObj1.Create(true);
co2:=TCountObj2.Create(true);
co3:=TCountObj3.Create(true);
//назначаем приорететы потокам
co1.Priority:=tpIdle;
co2.Priority:=tpLower;
co3.Priority:=tpNormal;
//запускаем потоки
co1.Resume;
co2.Resume;
co3.Resume;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
//уничтожаем потоки
co1.Terminate;
co2.Terminate;
co3.Terminate;
end;
end.
Текст модуля MyThread.
unit MyThread;
interface
uses
Classes, Sysutils;
type
TCountObj1 = class(TThread)
private
{ Private declarations }
index:Integer;
procedure UpdateLabel;
protected
procedure Execute; override;
end;
type
TCountObj2 = class(TThread)
private
{ Private declarations }
index:Integer;
procedure UpdateLabel;
protected
procedure Execute; override;
end;
type
TCountObj3 = class(TThread)
private
{ Private declarations }
index:Integer;
procedure UpdateLabel;
protected
procedure Execute; override;
end;
implementation
uses Main;
{ TCountObj1 }
procedure TCountObj1.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;
procedure TCountObj1.UpdateLabel;
begin
Form1.Label1.Caption:=IntToStr(Index);
end;
{ TCountObj2 }
procedure TCountObj2.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;
procedure TCountObj2.UpdateLabel;
begin
Form1.Label2.Caption:=IntToStr(Index);
end;
{ TCountObj3 }
procedure TCountObj3.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;
procedure TCountObj3.UpdateLabel;
begin
Form1.Label3.Caption:=IntToStr(Index);
end;
end.
Разберем принцип работы данной программы. После нажатия кнопки "Запустить" создаются и запускаются три потока с разными приоритетами. Для запуска можно обойтись без использования метода Resume, если передавать в метод Create параметром значение False. Далее потоки начинают параллельную работу: каждый поток увеличивает свой собственный счетчик. После нажатия кнопки "Остановить" для каждого потока произойдет вызов метода Terminate, и потоки будут уничтожены. Наглядность работы программы будет зависеть от тактовой частоты процессора: чем она выше, тем быстрее будет происходить увеличение счетчика. При слишком быстром изменении значений, можно увеличить значение, при достижении которого обнуляется счетчик, тогда работа программы будет более наглядной.
Текст этого примера можно взять здесь.
На следующем шаге мы рассмотрим, как с помощью потоков можно выполнять фоновые процедуры.