8. Отредактируйте главный файл модуля uMain.pas и добавьте модуль uPiThread к списку используемых модулей в секции интерфейса. Он должен выглядеть так:

uses

Windows, Massages, SysUtils, Variants, Classes, Graphics, Controls, Forms, StdCtrls, uPiThread;
9. В секции puhlic формы TfmMain добавьте ссыпку на создаваемую нить: PiThread : TPiThread;

10. Добавьте в модуль uMain две глобальньЕ переменные

GlcfcalPi : Extended;
GlobalGcunter : Iht64;

И метод UpdatePi:

procedure TfmMain.UpdatePi;
begin
if Islconic(Application.Handle) then Exit;
LaValue.Caption := FloatToStrF(GlobalPi, ffFrxed, 18, 18);
lalterNum. Caption : = IntToStr (GlobalCounter) + ' iterations';
end;

Этот метод, если вы обратили внимание, вызывается из потока посредством процедуры synchronize. Он отображает текущее значение приближения к числу "пи" и количество итераций.

В случае, если главное окно приложения свернуто, отображение не производится; так что после его развертывания вам, возможно, придется подождать некоторое время для обновления.

11. Выполните двойной щелчок на свободном месте рабочей области формы, при этом создастся шаблон метода FormCreate. Здесь мы отобразим значение системной константы Pi:

procedure TfinMain. FormCreate (Sender: TObject);
begin
laBuiltln.Caption := FloatToStrF(Pi, ffFrxed, 18, 18);
end;

12. Выберите на форме переключатель (его название cbcalculate) и назначьте событию 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.

Программирование в Delphi 7

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

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

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

Проблемы при синхронизации потоков

К сожалению, простота создания потоков подчас "компенсируется" сложностью их применения. Две типичные проблемы, с которыми программист может столкнуться при работе с потоками, - это тупики (deadlocks) и гонки (race conditions).

Тупики

Вероятно, вы не раз наблюдали на трамвайной остановке следующую забавную картину (рис. 29.6).

Программирование в Delphi 7

Рис 29.6. Ситуации тупиков возникают не только в программировании

Рисунок дает исчерпывающее пояснение ситуации тупиков. Тупики имеют место, когда поток ожидает ресурс, который в данный момент принадлежит другому потоку. Рассмотрим пример. Поток 1 захватывает ресурс А, и для того чтобы продолжать работу, ждет возможности захватить ресурс Б. В то же время Поток 2 захватывает ресурс Б и ждет возможности захватить ресурс А. Развитие этого сценария заблокирует оба потока; ни один из них не будет исполняться. Ресурсами могут выступать любые совместно используемые объекты системы - файлы, массивы в памяти, устройства ввода/вывода и т. п.


⇐ Предыдущая страница| |Следующая страница ⇒

Программирование в Delphi 7



Новости за месяц

  • Ноябрь
    2017
  • Пн
  • Вт
  • Ср
  • Чт
  • Пт
  • Сб
  • Вс