16221

Разработка многопоточных приложений

Лабораторная работа

Информатика, кибернетика и программирование

Лабораторная работа №9 Разработка многопоточных приложений Цель работы: Изучить принципы организации параллельных вычислений в отдельных потоках Постановка задачи: Разработать приложение содержащее два потока. В первом потоке случайным образом формировать парам...

Русский

2013-06-20

402.5 KB

15 чел.

Лабораторная работа №9

Разработка многопоточных приложений

Цель работы: Изучить принципы организации параллельных вычислений в отдельных потоках

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

 где 1..9,  1..6,  3..5,  ,  .

Для построения геометрических фигур разработать класс. Предусмотреть изменение приоритетов в потоках.

Краткие теоретические сведения:

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

Для создания дополнительного потока в программах Delphi предназначен специальный модуль потока в репозитории он обозначен пиктограммой Thread Obiect. При выборе этого модуля Delphi запрашивает имя класса, который будет дочерним для основополагающего класса TThread. Необходимость наследования связана с тем, что класс TThread содержит абстрактный метод Execute, который, собственно, и должен исполняться в рамках нового потока и который, следовательно, обязан перекрываться в потомках.

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

Текст программы:

<Project>

<UDrawings>

unit UDrawings;

interface

uses Graphics, Windows, SysUtils;

type

 TObjectProcedure=procedure of object;

type

 TDrawings = class

 private

   i: integer;

   A: integer;

   B: integer;

   C: integer;

   re, gr, bl: byte;

   reb, grb, blb: boolean;

   redrawing: boolean;

   doredrawing: boolean;

   FCanvas: TCanvas;

   w, h: integer;

   FReady: boolean;

 protected

 public

   constructor Create(AA, AB, AC: integer; Canvas: TCanvas; AWidth, AHeight: integer; ADoRedrawing: boolean); reintroduce;

   procedure Draw_Next();

   property Ready: boolean read FReady;

 end;

implementation

constructor TDrawings.Create(AA, AB, AC: integer; Canvas: TCanvas; AWidth, AHeight: integer; ADoRedrawing: boolean);

begin

 i:=0;

 A:=AA;

 B:=AB;

 C:=AC;

 w:=AWidth;

 h:=AHeight;

 doredrawing:=ADoRedrawing;

 FReady:=false;

 FCanvas:=Canvas;

 FCanvas.MoveTo((w div 2), (h div 2));

 FCanvas.Pen.Width:=(w div 15);

 FCanvas.Brush.Style:=bsSolid;

 FCanvas.Brush.Color:=clBlack;

 FCanvas.FillRect(Canvas.ClipRect);

 //randomize;

 re:=random(255);

 gr:=random(255);

 bl:=random(255);

 case random(3) of

 0:  reb:=true;

 1:  grb:=true;

 2:  blb:=true;

 end;

 redrawing:=false;

end;

procedure TDrawings.Draw_Next;

const

 dfi=Pi/200;

var

 r, x, y: double;

begin

   //MessageBox(0, PChar(Format(': %d :', [i])), '', 0);

   r:=sin((i)*dfi*C);

   x:=r*cos(A*(i)*dfi);

   y:=r*sin(B*(i)*dfi);

   if reb then

     re:=random(255);

   if grb then

     gr:=random(255);

   if blb then

     bl:=random(255);

   FCanvas.Pen.Color:=RGB(re, gr, bl);

   FCanvas.LineTo(round(x*(w div 2 - FCanvas.Pen.Width)+(w div 2)), round(y*(h div 2 - FCanvas.Pen.Width)+(h div 2)));

   inc(i);

   if (i>400) then

   begin

     i:=i-400;

     //Form1.Image1.Canvas.Pen.Color:=RGB(100+random(155), random(155), random(155));

       redrawing:=not redrawing;

       reb:=false;

       grb:=false;

       blb:=false;

       if not redrawing then

       begin

         re:=random(255);

         gr:=random(255);

         bl:=random(255);

         case random(3) of

         0:  reb:=true;

         1:  grb:=true;

         2:  blb:=true;

         end;

         a:=random(20)+1;

         b:=random(20)+1;

         c:=random(20)+1;

       end

       else

       begin

         re:=0;

         gr:=0;

         bl:=0;

       end;

       if not doredrawing then

         FReady:=true

       else if not redrawing then

         FReady:=true;

   end;

end;

end.

<UIntegrals>

unit UIntegral;

interface

uses Chart;

const funcCount=4;

type

    TValueChangedFunc=procedure (newValue: Extended) of object;

    TIntegral=class

     private

       FValueMin: Extended;//Нижняя граница

       FValueMax: Extended;//Верхняя граница

       FValueH: Extended; //Ширина шага

       FRes: Extended;    //Результат

       FValueN: Integer;  //Количество шагов

       FCalcMethod: Byte; //Номер выбранного способа подсчёта (0-трап.; 1-лев.прямоуг.; 2-прав.прямоуг.; 3-средн.прямоуг)

       FAutoRedraw: Boolean; //Перерисовывать при изменении хотя бы одного параметра

       FChart: TChart;

       FMaxY: extended;

       FOnMinChanged: TValueChangedFunc;

       FOnMaxChanged: TValueChangedFunc;

       FOnNChanged: TValueChangedFunc;

       FOnHChanged: TValueChangedFunc;

       FOnRecalc: TValueChangedFunc;

       FIsError: boolean;

       FSeries: byte;

     protected

       procedure SetN(newN: integer); virtual;

       procedure SetH(newH: Extended); virtual;

       procedure SetMin(newMin: Extended); virtual;

       procedure SetMax(newMax: Extended); virtual;

       procedure SetCalcMethod(newMethod: byte); virtual;

       procedure SetChart(newChart: TChart); virtual;

     public

       constructor Create(newSeries: byte=0);

       destructor Destroy; override;

       property A: Extended read FValueMin write SetMin;//Нижняя граница

       property B: Extended read FValueMax write SetMax;//Верхняя граница

       property N: integer read FValueN write SetN default 10;//Количество шагов

       property H: Extended read FValueH write SetH;//Ширина одного шага

       property CalcMethod: byte read FCalcMethod write SetCalcMethod default 0;   //Номер выбранного способа подсчёта (0-трап.; 1-лев.прямоуг.; 2-прав.прямоуг.; 3-средн.прямоуг)

       property Chart: TChart read FChart write SetChart;

       property AutoRedraw: boolean read FAutoRedraw write FAutoRedraw default true;//Перерисовывать при изменении хотя бы одного параметра

       property Res: Extended read FRes;

       property IsError: boolean read FIsError;

       property MaxY: Extended read FMaxY;

       //События (на изменение каждого из параметров)

       property OnMinChanged: TValueChangedFunc read FOnMinChanged write FOnMinChanged default nil;

       property OnMaxChanged: TValueChangedFunc read FOnMaxChanged write FOnMaxChanged default nil;

       property OnNChanged: TValueChangedFunc read FOnNChanged write FOnNChanged default nil;

       property OnHChanged: TValueChangedFunc read FOnHChanged write FOnHChanged default nil;

       property OnRecalc: TValueChangedFunc read FOnRecalc write FOnRecalc default nil;

       //Подынтегральная функция

       function f(x: Extended): Extended; virtual; abstract;

       //Функции подсчёта результата

       procedure ReCalc(); virtual;

       function calc_trapezium: Extended; virtual;

       function calc_rectangle_left: Extended; virtual;

       function calc_rectangle_right: Extended; virtual;

       function calc_rectangle_media: Extended; virtual;

       //Функции вывода информации в компонент TChart

       procedure Redraw(); virtual;

       procedure draw_f; virtual;

       procedure draw_trapezium; virtual;

       procedure draw_rectangle_left; virtual;

       procedure draw_rectangle_right; virtual;

       procedure draw_rectangle_media; virtual;

    end;

    TIntegral1=class(TIntegral)

     public

       function f(x: Extended): Extended; override;

    end;

    TIntegral2=class(TIntegral)

     public

       function f(x: Extended): Extended; override;

    end;

    TIntegral3=class(TIntegral)

     public

       function f(x: Extended): Extended; override;

    end;

    TIntegral4=class(TIntegral)

     public

       function f(x: Extended): Extended; override;

    end;

    TIntegral5=class(TIntegral)

     public

       function f(x: Extended): Extended; override;

    end;

implementation

constructor TIntegral.Create(newSeries: byte = 0);

begin

 inherited Create();

 FValueMax:=1;

 FValueMin:=0;

 FValueH:=0.1;

 FAutoRedraw:=true;

 FSeries:=newSeries;

 FIsError:=true;

 N:=10;

end;

destructor TIntegral.Destroy;

begin

 inherited Destroy;

end;

procedure TIntegral.SetN(newN: integer);

begin

 FValueN:=newN;

 if FValueN<1 then

   FValueN:=1;

 FValueH:=(FValueMax-FValueMin)/FValueN;

 

 if (AutoRedraw) then

   Redraw();

 ReCalc();

 if Assigned(FOnNChanged) then

   FOnNChanged(FValueN);

 if Assigned(FOnHChanged) then

   FOnHChanged(FValueH);

end;

procedure TIntegral.SetH(newH: Extended);

begin

 FValueN:=round((FValueMax-FValueMin)/newH)+1;

 FValueH:=(FValueMax-FValueMin)/FValueN;

 

 if (AutoRedraw) then

   Redraw();

 ReCalc();

 if Assigned(FOnNChanged) then

   FOnNChanged(FValueN);

 if Assigned(FOnHChanged) then

   FOnHChanged(FValueH);

end;

procedure TIntegral.SetMin(newMin: Extended);

begin

 FValueMin:=newMin;

 FValueH:=(FValueMax-FValueMin)/FValueN;

 

 if (AutoRedraw) then

   Redraw();

 ReCalc();

 if Assigned(FOnMinChanged) then

   FOnMinChanged(newMin);

end;

procedure TIntegral.SetMax(newMax: Extended);

begin

 FValueMax:=newMax;

 FValueH:=(FValueMax-FValueMin)/FValueN;

 

 if (AutoRedraw) then

   Redraw();

 ReCalc();

 

 if Assigned(FOnMaxChanged) then

   FOnMaxChanged(newMax);

end;

procedure TIntegral.SetChart(newChart: TChart);

begin

 FChart:=newChart;

 if (AutoRedraw) then

   Redraw();

end;

procedure TIntegral.SetCalcMethod(newMethod: byte);

begin

 if (newMethod in [0..3]) then

 begin

   FCalcMethod:=newMethod;

   if (AutoRedraw) then

     Redraw();

   ReCalc();

 end;

end;

procedure TIntegral.ReCalc;

begin

   FRes:=0;

   FIsError:=true;

   if FValueMin<FValueMax then

   begin

     case FCalcMethod of

     0: FRes:=calc_trapezium();

     1: FRes:=calc_rectangle_left();

     2: FRes:=calc_rectangle_right();

     3: FRes:=calc_rectangle_media();

     end;

     FIsError:=false;

   end;

   

   if Assigned(FOnRecalc) then

     FOnRecalc(FRes);

end;

function TIntegral.calc_trapezium: Extended;

var x: extended;

   i: integer;

begin

 Result:=0;

 x:=FValueMin;

 for i:=1 to FValueN do

 begin

   Result:=Result+(f(x)+f(x+FValueH))/2*FValueH;

   x:=x+FValueH;

 end;

end;

function TIntegral.calc_rectangle_left:Extended;

var i:integer;

   x:extended;

begin

 Result:=0;

 x:=FValueMin;

 for i:=1 to n do

   begin

     Result:=Result+FValueH*f(x);

     x:=x+FValueH;

   end;

end;

function TIntegral.calc_rectangle_right:Extended;

var i:integer;

   x:extended;

begin

 Result:=0;

 x:=FValueMin;

 for i:=1 to n do

   begin

     Result:=Result+FValueH*f(x+FValueH);

     x:=x+FValueH;

   end;

end;

function TIntegral.calc_rectangle_media:Extended;

var i:integer;

   x:extended;

begin

 Result:=0;

 x:=FValueMin;

 for i:=1 to n do

   begin

     Result:=Result+FValueH*f(x+FValueH/2);

     x:=x+FValueH;

   end;

end;

procedure TIntegral.Redraw;

begin

 if (Assigned(FChart) and (FValueMin<FValueMax)) then

 begin

   draw_f;

   case FCalcMethod of

   0: draw_trapezium();

   1: draw_rectangle_left();

   2: draw_rectangle_right();

   3: draw_rectangle_media();

   end;

 end

 else if Assigned(FChart) then

 begin

   Chart.Series[FSeries].Clear;

   Chart.Series[FSeries+1].Clear;

   FMaxY:=0;

 end;

end;

procedure TIntegral.draw_f;

var rightRange, x, h1: extended;

begin

 if Assigned(FChart) then

 begin

   FChart.Series[FSeries+1].Clear;

   rightRange:=FValueMax+(FValueMax-FValueMin)*0.1;

   x:=FValueMin-(FValueMax-FValueMin)*0.1;

   h1:=(rightRange-x)/50;

   rightRange:=rightRange+h1;

   while x<=rightRange do

   begin

     FChart.Series[FSeries+1].AddXY(x, f(x));

     x:=x+h1;

   end;

   FMaxY:=f(x)*1.05;

 end;

end;

procedure TIntegral.draw_trapezium;

var x: extended;

   i: integer;

begin

 if Assigned(FChart) then

 begin

   draw_f;

   FChart.Series[FSeries].Clear;

   x:=FValueMin;

   for i:=0 to FValueN do

   begin

     FChart.Series[FSeries].AddXY(x, f(x));

     x:=x+FValueH;

   end;

 end;

end;

procedure TIntegral.draw_rectangle_left;

var x: extended;

   i: integer;

begin

 if Assigned(FChart) then

 begin

   draw_f;

   FChart.Series[FSeries].Clear;

   x:=FValueMin;

   for i:=1 to FValueN do

   begin

     FChart.Series[FSeries].AddXY(x, f(x));

     FChart.Series[FSeries].AddXY(x+FValueH, f(x));

     x:=x+FValueH;

   end;

 end;

end;

procedure TIntegral.draw_rectangle_right;

var x: extended;

   i: integer;

begin

 if Assigned(FChart) then

 begin

   draw_f;

   FChart.Series[FSeries].Clear;

   x:=FValueMin;

   for i:=1 to FValueN do

   begin

     FChart.Series[FSeries].AddXY(x, f(x+FValueH));

     FChart.Series[FSeries].AddXY(x+FValueH, f(x+FValueH));

     x:=x+FValueH;

   end;

 end;

end;

procedure TIntegral.draw_rectangle_media;

var x: extended;

   i: integer;

begin

 if Assigned(Chart) then

 begin

   draw_f;

   FChart.Series[FSeries].Clear;

   x:=FValueMin;

   for i:=1 to FValueN do

   begin

     Chart.Series[FSeries].AddXY(x, f(x+FValueH/2));

     Chart.Series[FSeries].AddXY(x+FValueH, f(x+FValueH/2));

     x:=x+FValueH;

   end;

 end;

end;

function TIntegral1.f(x: Extended): Extended;

begin

 Result:=sqr(x);

end;

function TIntegral2.f(x: Extended): Extended;

begin

 Result:=sqr(x)*x;

end;

function TIntegral3.f(x: Extended): Extended;

begin

 Result:=exp(x);

end;

function TIntegral4.f(x: Extended): Extended;

begin

 Result:=exp(sqr(x));

end;

function TIntegral5.f(x: Extended): Extended;

begin

 Result:=abs(x);

end;

end.

<UMain>

unit UMain;

interface

uses

 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

 Dialogs, ExtCtrls, Buttons, StdCtrls, TeeProcs, TeEngine, Chart, Series, UIntegral, UDrawings;

type

 TForm1 = class(TForm)

   Image1: TImage;

   SpeedButton1: TSpeedButton;

   Panel1: TPanel;

   Panel2: TPanel;

   Panel4: TPanel;

   SpeedButton2: TSpeedButton;

   Bevel1: TBevel;

   Label1: TLabel;

   ScrollBar1: TScrollBar;

   SpeedButton3: TSpeedButton;

   Chart1: TChart;

   Series1: TLineSeries;

   Label2: TLabel;

   Label3: TLabel;

   Label4: TLabel;

   Edit1: TEdit;

   Label5: TLabel;

   Edit2: TEdit;

   Label6: TLabel;

   Label7: TLabel;

   ScrollBar2: TScrollBar;

   SpeedButton4: TSpeedButton;

   SpeedButton5: TSpeedButton;

   SpeedButton6: TSpeedButton;

   Label8: TLabel;

   Edit3: TEdit;

   Edit4: TEdit;

   Label9: TLabel;

   Label10: TLabel;

   Series2: TAreaSeries;

   Edit5: TEdit;

   Label11: TLabel;

   Edit6: TEdit;

   Label12: TLabel;

   CheckBox1: TCheckBox;

   CheckBox2: TCheckBox;

   procedure SpeedButton1Click(Sender: TObject);

   procedure ScrollBar1Change(Sender: TObject);

   procedure FormCreate(Sender: TObject);

   procedure SpeedButton2Click(Sender: TObject);

   procedure SpeedButton3Click(Sender: TObject);

   procedure SpeedButton4Click(Sender: TObject);

   procedure SpeedButton6Click(Sender: TObject);

   procedure SpeedButton5Click(Sender: TObject);

   procedure ScrollBar2Change(Sender: TObject);

   procedure FormDestroy(Sender: TObject);

   procedure CheckBox1Click(Sender: TObject);

 private

   { Private declarations }

 public

   { Public declarations }

 end;

type

 TDrawingThread = class(TThread)

 private

   { Private declarations }

   d: TDrawings;

 protected

   procedure Execute; override;

   procedure Draw;

 end;

 TIntegralThread = class(TThread)

 private

   { Private declarations }

   time: byte;

 protected

   procedure Execute; override;

   procedure IntegralCalculation;

   procedure SynchronizeTime;

 end;

var

 Form1: TForm1;

 t: TDrawingThread;

 ti: TIntegralThread;

implementation

{$R *.dfm}

procedure TIntegralThread.Execute;

var i: integer;

begin

 while not Terminated do

 begin

   Synchronize(IntegralCalculation);

   for i:=5 downto 0 do

   begin

     time:=i;

     Synchronize(SynchronizeTime);

     sleep(1000);

   end;

 end;

end;

procedure TIntegralThread.SynchronizeTime;

begin

 Form1.Label12.Caption:=inttostr(time);

end;

procedure TIntegralThread.IntegralCalculation;

var

 integ: TIntegral;

begin

 case random(5) of

   0:begin

     integ:=TIntegral1.Create();

     Form1.Edit3.Text:='y=x^2';

     end;

   1:begin

     integ:=TIntegral2.Create();

     Form1.Edit3.Text:='y=x^3';

     end;

   2:begin

     integ:=TIntegral3.Create();

     Form1.Edit3.Text:='y=e^x';

     end;

   3:begin

     integ:=TIntegral4.Create();

     Form1.Edit3.Text:='y=e^(x^2)';

     end;

   4:begin

     integ:=TIntegral5.Create();

     Form1.Edit3.Text:='y=|x|';

     end;

 end;

 integ.Chart:=Form1.Chart1;

 integ.CalcMethod:=random(4);

 integ.A:=random*5+2;

 integ.B:=integ.A+random*5;

 integ.N:=random(50)+10;

 Form1.Edit1.Text:=floattostr(integ.A);

 Form1.Edit2.Text:=floattostr(integ.B);

 Form1.Edit4.Text:=inttostr(integ.N);

 Form1.Edit6.Text:=floattostr(integ.Res);

 case integ.CalcMethod of

 0: Form1.Edit5.Text:='Трапеций';

 1: Form1.Edit5.Text:='Левых прямоугольников';

 2: Form1.Edit5.Text:='Правых прямоугольников';

 3: Form1.Edit5.Text:='Средних прямоугольников';

 end;

 integ.Free;

end;

/////////////////////////////////////////////////////////

procedure TDrawingThread.Execute;

 { Place thread code here }

begin

 randomize;

 //Form1.Image1.Canvas.Pen.Color:=RGB(random(255), random(255), random(255));

   randomize;

  while not Terminated do

  begin

     Synchronize(Draw);

     while not d.Ready and not Terminated do

     begin

     Synchronize(d.Draw_Next);

     if Form1.CheckBox1.Checked then

       sleep(10);

   //MessageBox(0, '', '', 0);

     end;

     d.Free;

    sleep(1000);

  end;

end;

procedure TDrawingThread.Draw();

begin

 d:=TDrawings.Create(random(20)+1, random(20)+1, random(20)+1, Form1.Image1.Canvas, Form1.Image1.Width, Form1.Image1.Height, Form1.CheckBox2.Checked);

end;

procedure TForm1.SpeedButton1Click(Sender: TObject);

begin

 t:=TDrawingThread.Create(true);

 t.Priority:=TThreadPriority(ScrollBar1.Position-1);

 t.FreeOnTerminate:=true;

 t.Resume;

 SpeedButton1.Enabled:=false;

 SpeedButton2.Enabled:=true;

 SpeedButton3.Enabled:=true;

end;

////////////////////////////////////

procedure TForm1.ScrollBar1Change(Sender: TObject);

begin

 if (t<>nil) then

 begin

   t.Suspend;

   case (ScrollBar1.Position) of

     1: t.Priority:=tpIdle;

     2: t.Priority:=tpLowest;

     3: t.Priority:=tpLower;

     4: t.Priority:=tpNormal;

     5: t.Priority:=tpHigher;

     6: t.Priority:=tpHighest;

     7: t.Priority:=tpTimeCritical;

   end;

   t.Resume;

 end;

 case (ScrollBar1.Position) of

     1: Label3.Caption:='tpIdle';

     2: Label3.Caption:='tpLowest';

     3: Label3.Caption:='tpLower';

     4: Label3.Caption:='tpNormal';

     5: Label3.Caption:='tpHigher';

     6: Label3.Caption:='tpHighest';

     7: Label3.Caption:='tpTimeCritical';

   end;

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

 ScrollBar1Change(nil);

 ScrollBar2Change(nil);

end;

procedure TForm1.SpeedButton2Click(Sender: TObject);

begin

 if (t<>nil) then

 begin

   t.Terminate;

   t:=nil;

 end;

 SpeedButton3.Down:=false;

 SpeedButton1.Enabled:=true;

 SpeedButton2.Enabled:=false;

 SpeedButton3.Enabled:=false;

 Image1.Canvas.FillRect(Image1.Canvas.ClipRect);

end;

procedure TForm1.SpeedButton3Click(Sender: TObject);

begin

 if (t<>nil) then

 begin

   if (SpeedButton3.Down) then

     t.Suspend

   else

     t.Resume;

 end;

end;

procedure TForm1.SpeedButton4Click(Sender: TObject);

begin

 ti:=TIntegralThread.Create(true);

 ti.Priority:=TThreadPriority(ScrollBar2.Position-1);

 ti.FreeOnTerminate:=true;

 ti.Resume;

 SpeedButton4.Enabled:=false;

 SpeedButton5.Enabled:=true;

 SpeedButton6.Enabled:=true;

end;

procedure TForm1.SpeedButton6Click(Sender: TObject);

begin

 if (ti<>nil) then

 begin

   ti.Terminate;

   ti:=nil;

 end;

 SpeedButton5.Down:=false;

 SpeedButton4.Enabled:=true;

 SpeedButton5.Enabled:=false;

 SpeedButton6.Enabled:=false;

 Chart1.Series[0].Clear;

 Chart1.Series[1].Clear;

end;

procedure TForm1.SpeedButton5Click(Sender: TObject);

begin

 if (ti<>nil) then

 begin

   if (SpeedButton5.Down) then

     ti.Suspend

   else

     ti.Resume;

 end;

end;

procedure TForm1.ScrollBar2Change(Sender: TObject);

begin

 if (ti<>nil) then

 begin

   ti.Suspend;

   case (ScrollBar2.Position) of

     1: ti.Priority:=tpIdle;

     2: ti.Priority:=tpLowest;

     3: ti.Priority:=tpLower;

     4: ti.Priority:=tpNormal;

     5: ti.Priority:=tpHigher;

     6: ti.Priority:=tpHighest;

     7: ti.Priority:=tpTimeCritical;

   end;

   ti.Resume;

 end;

 case (ScrollBar2.Position) of

     1: Label7.Caption:='tpIdle';

     2: Label7.Caption:='tpLowest';

     3: Label7.Caption:='tpLower';

     4: Label7.Caption:='tpNormal';

     5: Label7.Caption:='tpHigher';

     6: Label7.Caption:='tpHighest';

     7: Label7.Caption:='tpTimeCritical';

   end;

end;

procedure TForm1.FormDestroy(Sender: TObject);

begin

 if (t<>nil) then

 begin

   t.Terminate;

 end;

 if (ti<>nil) then

 begin

   ti.Terminate;

 end;

end;

procedure TForm1.CheckBox1Click(Sender: TObject);

begin

 if not CheckBox1.Checked then

   CheckBox2.Checked:=false;

 CheckBox2.Enabled:=CheckBox1.Checked;

end;

end.

Результаты работы программы:

Выводы: таким образом, мы изучили


 

А также другие работы, которые могут Вас заинтересовать

44946. Организация вычисляемого перехода 41.46 KB
  Вычисляемый переход осуществляется при помощи команды ddwf PCF которая формально описывается так: сложить содержимое регистров W и PC с сохранением результата сложения в регистре PC имеется ввиду младший байт счетчика команд с названием PCL. Для вычисляемого перехода адрес в PC на момент исполнения команды ddwf PCF является как бы начальной точкой отсчета т. число находящееся в регистре W на момент исполнения команды ddwf PCF которое и будет приращением счетчика команд PC.
44947. Динамическая индикация 59.87 KB
  Для краткости эти регистры обозначим под названиями LED с соответствующей нумерацией. Например если результат измерения подсчета нужно вывести на индикацию как 4 разрядное десятичное число то двоичный результат измерения “прогоняется†через двоично-десятичное преобразование о нем позднее в итоге которого результат измерения помещается в младшие полубайты 4х регистров LED от LED0 до LED3.0 MHz ; DtL equ 0Ch DtH equ 0Dh D_H equ 0Eh D_L equ 0Fh Step equ 1Bh Led0 equ 1Ch Led1...
44949. Работа с EEPROM памятью данных 61.93 KB
  Поставим перед собой достаточно простую и конкретную задачу (что-то типа задания на первоначальную разработку). Допустим, что в ходе исполнения программы нужно изменить (модифицировать) содержимое пяти ячеек EEPROM памяти, начиная с адреса 7. Для простоты модификации (и для обеспечения наглядности наблюдения за происходящими в EEPROM памяти изменениями) к первому числу (по адресу 7) необходимо добавить 1...
44950. Однокристальные микроконтроллеры серии PIC 231 KB
  Микроконтроллеры семейств PIC (Peripheral Interface Controller) компании Microchip, обладающие особой популярностью, построены на основе передовых технологий микроконтроллеров. Им свойственны следующие особенности: электрически программируемые пользователем ППЗУ, минимальное энергопотребление, высокая производительность, хорошо развитая RISC-архитектура
44952. Автоколебательный мультивибратор 33.87 KB
  Проанализируем нашу программу, реализующую функцию автоколебательного мультивибратора, с одним выходом. Форма сигнала меандр (скважность, т.е. отношение периода к длительности импульса – 2). Под этот выход можно назначить любой из выводов порта А или В...
44953. Устройство формирования сигнала тонального вызова 87.52 KB
  Полупериоды формируем используя €œзакольцовку рабочей точки программы в подпрограммах задержки по аналогии с программой Multi. К моменту начала составления текста программы желательно определиться с как можно большим количеством исходных данных. Так как программа должна исполняться непрерывно то в случае нахождения устройства в режиме ожидания включения на передачу рабочая точка программы должна €œзакольцеваться€ до последующего нажатия на кнопку в какой-нибудь подпрограмме. Часто такого рода закольцовки осуществляют в...
44954. Сканирование с прерыванием 110.21 KB
  Определимся с терминологией применяемой при описании программы работы устройства. Для удобства объяснения и восприятия целесообразно разделить рабочую часть программы на две части. Условимся называть группу команд в которой осуществляется сканирование каналов на наличие сигнала прерывания “основным телом†программы а часть которая отрабатывается после ухода в прерывание как подпрограмму прерывания. Следовательно речь идет о необходимости “ухода†рабочей точки программы на время наличия сигнала прерывания в подпрограмму...