5. Когда появится диалоговое окно для именования объекта поток, введите TPiThread и нажмите клавишу <Enter> (Рисунок 29.4). Помимо этого, при желании, вы можете присвоить создаваемому потоку имя, установив флажок Named Thread и задав имя в поле Thread Name. Так как имя потока используется только для удобства обозначения, эту возможность мы использовать не будем.
Delphi создаст новый модуль и поместит в него шаблон для нового потока.
6. Код, вносимый в метод Execute, вычисляет число я, используя сходимость бесконечного ряда Лейбница:
Pi = 4 - 4/3 + 4/5 - 4/7 + 4/9 -...
Разумеется, отображать новое значение после каждой итерации — это то же самое, что стрелять из пушки по воробьям. На отображение информации система потратит в десятки раз больше времени, чем на собственно вычисления. Поэтому мы ввели константу updatePeriod, которая регулирует периодичность отображения текущего значения.
Код метода Execute показан ниже:
const
// Лучше использовать нечетное число для того, чтобы избежать эффекта // мерцания UpdatePeriod = 1000001;
procedure TPiThread.Execute; var sign : Integer;
PiValue, PrevValue : Extended; i : Int64;
begin
{ Place thread code here } PiValue := 4; sign := -1; i := 0; repeat Inc(i);
PrevValue := PiValue;
PiValue := PiValue + sign * 4 / (2*i+l); sign := -sign;
if i mod UpdatePeriod = 0 then
begin
GlobalPi := PiValue; GlobalCounter := i; Synchronize(fmMain.UpdatePi);
end;
until Terminated or (Abs(PiValue - PrevValue)<1E-19); end;
7. Откройте меню File и выберите пункт Save As. Сохраните модуль с потоком как uPiThread.pas.
8. Отредактируйте главный файл модуля uMain.pas и добавьте модуль uPiThread к списку используемых модулей в секции интерфейса. Он должен выглядеть так:
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, StdCtrls, uPiThread;
9. В секции public формы TfmMain добавьте ссылку на создаваемую нить: PiThread : TPiThread;
10. Добавьте в модуль uMain две глобальные переменные
GlobalPi : Extended;
GlobalCounter : Int64;
и метод UpdatePi:
procedure TfmMain.UpdatePi;
begin
if Islconic(Application.Handle) then
Exit;
LaValue.Caption := FloatToStrF(GlobalPi, ffFixed, 18, 18);
lalterNum.Caption := IntToStr(GlobalCounter) + ' iterations';
end;
Этот метод, если вы обратили внимание, вызывается из потока посредством процедуры Synchronize. Он отображает текущее значение приближения к числу "пи" и количество итераций.
В случае, если главное окно приложения свернуто, отображение не производится; так что после его развертывания вам, возможно, придется подождать некоторое время для обновления.
11. Выполните двойной щелчок на свободном месте рабочей области формы, при этом создастся шаблон метода FormCreate. Здесь мы отобразим значение системной константы р±:
procedure TfmMain.FormCreate(Sender: TObject);
begin
laBuiltln.Caption := FloatToStrF(Pi, ffFixed, 18, 18); end;
12. Выберите на форме переключатель (его название cbcalcuiate) и назначьте событию Onclick код, создающий и уничтожающий вычислительный поток в зависимости от состояния переключателя:
procedure TfmMain.cbCalculateClick(Sender: TObject);
begin if cbCalculate.Checked then
begin
PiThread := TPiThread.Create(True);
PiThread.FreeOnTerminate := True;
PiThread.Priority := tpLower;
PiThread.Resume; end else begin
if Assigned(PiThread) then PiThread.Terminate;
end;
end;
Таким образом, многопоточное приложение готово к запуску. Если все пройдет нормально, вы увидите картинку, подобную той, которая приведена на Рисунок 29.5.