Пример создания многопоточного приложения в Delphi

Этот раздел содержит описание шагов, необходимых для создания простого, но показательного примера многопоточного приложения. Мы будем пытаться вычислить число "пи" с максимальной точностью после запятой. Конечно, встроенная в Delphi константа Pi имеет достаточную точность, правильнее сказать — максимальную, допускаемую самым точным 10-байтным форматом для вещественных чисел Extended. Так что превзойти ее нам не удастся. Но этот пример использования потоков может послужить прологом для решения реальных задач.

Первый пример будет содержать два потока: главный (обрабатывающий ввод пользователя) и вычислительный; мы сможем изменять их свойства и наблюдать за реакцией. Итак, выполните следующую последовательность действий:

1. В среде Delphi откройте меню File и выберите пункт New Application.

2. Расположите на форме пять меток и один переключатель, как показано на рис. 29.2.

Переименуйте главную форму в fmMain.

3. Откройте меню File и выберите пункт Save Project As. Сохраните модуль как uMain, а проект — как Threads 1.

Рис. 29.2. Внешний вид формы для приложения Threads'1

4. Откройте меню File и выберите пункт New. Затем дважды щелкните на объекте типа поток (значок Thread Object). Откроется диалоговое окно New Items, показанное на рис. 29.3.

Рис. 29.3. Диалоговое окно New Items с выбранным объектом типа "поток"

Рис. 29.4. Диалоговое окно New Thread Object

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.

Рис. 29.5. Выполняющееся приложение Threads1

Пока один из авторов писал текст этого раздела, запущенное одновременно приложение Threadsl выполнило пять миллиардов итераций и приблизилось к встроенному значению Pi в десятом разряде. Интересно, насколько хватит терпения у вас?

Этот простой пример — первый шаг в усвоении того, как от базового класса rrhread можно порождать собственные классы. Из-за своей простоты он не лишен недостатков; более того — если бы вычислительных нитей было не одна, а более, кое-какие приемы были бы даже ошибочными. Но — об этом ниже.

 


Знаете ли Вы, что, как и всякая идолопоклонническая религия, релятивизм ложен в своей основе. Он противоречит фактам. Среди них такие:

1. Электромагнитная волна (в религиозной терминологии релятивизма - "свет") имеет строго постоянную скорость 300 тыс.км/с, абсурдно не отсчитываемую ни от чего. Реально ЭМ-волны имеют разную скорость в веществе (например, ~200 тыс км/с в стекле и ~3 млн. км/с в поверхностных слоях металлов, разную скорость в эфире (см. статью "Температура эфира и красные смещения"), разную скорость для разных частот (см. статью "О скорости ЭМ-волн")

2. В релятивизме "свет" есть мифическое явление само по себе, а не физическая волна, являющаяся волнением определенной физической среды. Релятивистский "свет" - это волнение ничего в ничем. У него нет среды-носителя колебаний.

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

4. В гравитационном релятивизме (ОТО) вопреки наблюдаемым фактам утверждается об угловом отклонении ЭМ-волн в пустом пространстве под действием гравитации. Однако астрономам известно, что свет от затменных двойных звезд не подвержен такому отклонению, а те "подтверждающие теорию Эйнштейна факты", которые якобы наблюдались А. Эддингтоном в 1919 году в отношении Солнца, являются фальсификацией. Подробнее читайте в FAQ по эфирной физике.

НОВОСТИ ФОРУМА

Форум Рыцари теории эфира


Рыцари теории эфира
 10.11.2021 - 12:37: ПЕРСОНАЛИИ - Personalias -> WHO IS WHO - КТО ЕСТЬ КТО - Карим_Хайдаров.
10.11.2021 - 12:36: СОВЕСТЬ - Conscience -> РАСЧЕЛОВЕЧИВАНИЕ ЧЕЛОВЕКА. КОМУ ЭТО НАДО? - Карим_Хайдаров.
10.11.2021 - 12:36: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от д.м.н. Александра Алексеевича Редько - Карим_Хайдаров.
10.11.2021 - 12:35: ЭКОЛОГИЯ - Ecology -> Биологическая безопасность населения - Карим_Хайдаров.
10.11.2021 - 12:34: ВОЙНА, ПОЛИТИКА И НАУКА - War, Politics and Science -> Проблема государственного терроризма - Карим_Хайдаров.
10.11.2021 - 12:34: ВОЙНА, ПОЛИТИКА И НАУКА - War, Politics and Science -> ПРАВОСУДИЯ.НЕТ - Карим_Хайдаров.
10.11.2021 - 12:34: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Вадима Глогера, США - Карим_Хайдаров.
10.11.2021 - 09:18: НОВЫЕ ТЕХНОЛОГИИ - New Technologies -> Волновая генетика Петра Гаряева, 5G-контроль и управление - Карим_Хайдаров.
10.11.2021 - 09:18: ЭКОЛОГИЯ - Ecology -> ЭКОЛОГИЯ ДЛЯ ВСЕХ - Карим_Хайдаров.
10.11.2021 - 09:16: ЭКОЛОГИЯ - Ecology -> ПРОБЛЕМЫ МЕДИЦИНЫ - Карим_Хайдаров.
10.11.2021 - 09:15: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Екатерины Коваленко - Карим_Хайдаров.
10.11.2021 - 09:13: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Вильгельма Варкентина - Карим_Хайдаров.
Bourabai Research - Технологии XXI века Bourabai Research Institution