Шаг 6.
Организация потоков в Delphi-приложениях.
Пример: потоки с разными приоритетами

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

    На форму следует поместить шесть компонетнов 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, и потоки будут уничтожены. Наглядность работы программы будет зависеть от тактовой частоты процессора: чем она выше, тем быстрее будет происходить увеличение счетчика. При слишком быстром изменении значений, можно увеличить значение, при достижении которого обнуляется счетчик, тогда работа программы будет более наглядной.

    Текст этого примера можно взять здесь.

    На следующем шаге мы рассмотрим, как с помощью потоков можно выполнять фоновые процедуры.




Предыдущий шаг Содержание Следующий шаг