close

Вход

Забыли?

вход по аккаунту

?

отчет по лаб 2

код для вставкиСкачать
 Министерство по науке и образования
Рязанский государственный радиотехнический университет
Кафедра ЭВМ
Отчет
о лабораторной работе №2
"Средства синхронизации потоков и их реализация в среде Delphi"
Выполнил: ст. гр. 742 б.1
Безкоровайный А.В
Свиридов А.Ю
Проверил: доц. каф ЭВМ Засорин С.В.
асс. Каф ЭВМ Моноскин А.В.
Рязань 2010 г.
Задание 1. Критические секции
Описание задания: движение автомобилей воспроизводится в одном компоненте, задача состоит в недопущении ими одновременного использования компонента.
Код программы:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, ExtCtrls,SyncObjs, Unit2;
type
TForm1 = class(TForm)
PaintBox1: TPaintBox;
TrackBar1: TTrackBar; TrackBar2: TTrackBar;
Button1: TButton; Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure TrackBar2Change(Sender: TObject);
private
{ Private declarations }
public
Thread: array[1..2] of TMoveThread;
c: TCriticalSection;
end;
var
Form1: TForm1;
Taxi00, Taxi01, RTaxi00, RTaxi01: TBitmap;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin c:=TCriticalSection.Create; end;
procedure TForm1.FormShow(Sender: TObject);
begin
Taxi00:=TBitmap.Create;
Taxi00.LoadFromFile('TaxiToTheRight.bmp');
RTaxi00:=TBitmap.Create;
RTaxi00.LoadFromFile('TaxiToTheRight.bmp');
Taxi01:=TBitmap.Create;
Taxi01.LoadFromFile('TaxiToTheLeft.bmp');
RTaxi01:=TBitmap.Create;
RTaxi01.LoadFromFile('TaxiToTheLeft.bmp');
Thread[1]:=TMoveThread.Create(Taxi00, Taxi01, PaintBox1);
Thread[1].Priority:=tpLowest;
Thread[2]:=TMoveThread.Create(RTaxi00, RTaxi01, PaintBox1);
Thread[2].Priority:=tpLowest;
TrackBar1.Tag:=1; TrackBar2.Tag:=2;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Taxi00.Free; Taxi01.Free;
RTaxi00.Free; RTaxi01.Free;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if not Thread[1].Suspended then Thread[1].Suspend;
if not Thread[2].Suspended then Thread[2].Suspend;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if Thread[1].Suspended then Thread[1].Resume;
if Thread[2].Suspended then Thread[2].Resume;
end;
procedure TForm1.TrackBar2Change(Sender: TObject);
var Priority: TThreadPriority;
i,k: Integer;
begin
k:=(Sender as TTrackBar).Tag;
Priority:=tpIdle;
for i:=0 to ((Sender as TTrackBar).Position-1) do Inc(Priority);
Thread[k].Priority:=Priority;
end;
end.
Код модуля:
unit Unit2;
interface
uses
Classes, Graphics, ExtCtrls;
type
TMoveThread = class(TThread)
private
FBox: TPaintBox;
b0, b1: TBitmap;
i: Integer;
procedure DoVisualSwap;
procedure DoVisual;
protected
procedure Execute; override;
public
constructor Create(a,b: TBitmap; c: TPaintBox);
end;
implementation
uses Unit1;
{ TMoveThread }
procedure TMoveThread.Execute;
begin
while True do
begin
Form1.c.Enter;
try
while i<(FBox.Width+b0.Width) do Synchronize(DoVisualSwap);
finally Form1.c.Leave;
end;
Form1.c.Enter;
try
while i>=(0-b0.Width) do Synchronize(DoVisual);
finally Form1.c.Leave;
end;
end;
end;
procedure TMoveThread.DoVisualSwap;
begin
with FBox do
begin
Canvas.Draw(i,0,b0);
Inc(i);
end;
end;
procedure TMoveThread.DoVisual;
begin
with FBox do
begin
Canvas.Draw(i, 0, b1);
Dec(i);
end;
end;
constructor TMoveThread.Create(a,b: TBitmap; c: TPaintBox);
begin
b0:=a; b1:=b;
FBox:=c;
inherited Create(False);
end;
end.
Запускаем программу (рис.1)
Рис.1
Изменяем скорость движения автомобиля и нажимаем на кнопку "Finish" (рис.2)
Задание 2. Объект Mutex
Описание задания: Движение автомобилей воспроизводится в одном компоненте, задача состоит в появлении второго автомобиля только через определенный интервал времени после первого.
Код программы:
unit Unit1;
interface
uses
Windows, Messages, SysUtils,Variants,Classes,Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, ExtCtrls, Unit2, Spin, IPCthrd;
type
TForm1 = class(TForm)
PaintBox1: TPaintBox;
Button1: TButton; Button2: TButton;
SpinEdit1: TSpinEdit;
Label1: TLabel; Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure SpinEdit1Change(Sender: TObject);
public
Thread: array[1..2] of TMoveThread;
m: TMutex;
Time: Byte;
end;
var
Form1: TForm1;
Taxi00, Taxi01, RTaxi00, RTaxi01: TBitmap;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
m:=TMutex.Create('mutex');
Time:=100;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
Taxi00:=TBitmap.Create;
Taxi00.LoadFromFile('TaxiToTheRight.bmp');
RTaxi00:=TBitmap.Create;
RTaxi00.LoadFromFile('TaxiToTheRight.bmp');
Taxi01:=TBitmap.Create;
Taxi01.LoadFromFile('TaxiToTheLeft.bmp');
RTaxi01:=TBitmap.Create;
RTaxi01.LoadFromFile('TaxiToTheLeft.bmp');
Thread[1]:=TMoveThread.Create(Taxi00, Taxi01, PaintBox1);
Thread[1].Priority:=tpLowest;
Thread[2]:=TMoveThread.Create(RTaxi00, RTaxi01, PaintBox1);
Thread[2].Priority:=tpLowest;
SpinEdit1.Value := 100;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Taxi00.Free; Taxi01.Free; RTaxi00.Free; RTaxi01.Free;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if not Thread[1].Suspended then Thread[1].Suspend;
if not Thread[2].Suspended then Thread[2].Suspend;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if Thread[1].Suspended then Thread[1].Resume;
if Thread[2].Suspended then Thread[2].Resume;
end;
procedure TForm1.SpinEdit1Change(Sender: TObject);
begin Time:=Byte(SpinEdit1.Value); end;
end.
Код модуля:
unit Unit2;
interface
uses
Classes, Graphics, ExtCtrls, SysUtils;
type
TMoveThread = class(TThread)
private
FBox: TPaintBox;
b0, b1: TBitmap;
i: Integer;
procedure DoVisualSwap;
procedure DoVisual;
protected
procedure Execute; override;
public
constructor Create(a,b: TBitmap; c: TPaintBox);
end;
implementation
uses Unit1;
{ TMoveThread }
constructor TMoveThread.Create(a,b: TBitmap; c: TPaintBox);
begin
b0:=a; b1:=b;
FBox:=c;
inherited Create(False);
end;
procedure TMoveThread.DoVisualSwap;
begin
with FBox do
begin
Canvas.Draw(i,0,b0);
Inc(i);
end;
end;
procedure TMoveThread.DoVisual;
begin
with FBox do
begin
Canvas.Draw(i, 0, b1);
Dec(i);
end;
end;
procedure TMoveThread.Execute;
begin
while True do
begin
Form1.m.Get(Form1.Time);
try
while i<(FBox.Width+b0.Width) do begin (DoVisualSwap); end;
finally Form1.m.Release;
end;
Form1.m.Get(Form1.Time);
try
while i>=(0-b0.Width) do begin Synchronize(DoVisual); end;
finally Form1.m.Release;
end;
Suspend;
end;
end;
end.
Запускаем программу (рис.3)
Рис.3
Нажимаем на "Start" (рис.4)
Рис.4
Увеличиваем время задержки (рис.5)
Рис.5
Задание 3. Событие
Описание задания. Автомобили перевозят пассажиров. Задача состоит в недопущении поездок автомобиля без пассажиров. В этом задании создается приложение, в котором случайным образом наступает событие - появление пассажира. Автомобили могут перевозить пассажиров с определенной скоростью.
Код программы:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ExtCtrls,SyncObjs, Unit2, Spin;
type
TForm1 = class(TForm)
PaintBox1: TPaintBox; PaintBox2: TPaintBox;
TrackBar1: TTrackBar; TrackBar2: TTrackBar;
Button1: TButton; Button2: TButton;
SpinEdit1: TSpinEdit; SpinEdit2: TSpinEdit;
SpinEdit3: TSpinEdit; Timer1: TTimer;
Label1: TLabel; Label2: TLabel;
Label3: TLabel; Label4: TLabel;
procedure FormShow(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure TrackBar2Change(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure SpinEdit3Change(Sender: TObject);
public
Time: Integer;
Thread: array[1..2] of TMoveThread;
end;
var
Form1: TForm1;
Taxi00, Taxi01, RTaxi00, RTaxi01: TBitmap;
implementation
{$R *.dfm}
procedure TForm1.FormShow(Sender: TObject);
begin
Taxi00:=TBitmap.Create;
Taxi00.LoadFromFile('TaxiToTheRight.bmp');
RTaxi00:=TBitmap.Create;
RTaxi00.LoadFromFile('TaxiToTheRight.bmp');
Taxi01:=TBitmap.Create;
Taxi01.LoadFromFile('TaxiToTheLeft.bmp');
RTaxi01:=TBitmap.Create;
RTaxi01.LoadFromFile('TaxiToTheLeft.bmp');
Thread[1]:=TMoveThread.Create(Taxi00, Taxi01, PaintBox1);
Thread[1].Priority:=tpLowest;
Thread[2]:=TMoveThread.Create(RTaxi00, RTaxi01, PaintBox2);
Thread[2].Priority:=tpLowest;
TrackBar1.Tag:=1; TrackBar2.Tag:=2;
Time:=1000; SpinEdit3.Value:=Time;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Taxi00.Free; Taxi01.Free; RTaxi00.Free; RTaxi01.Free;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if not Thread[1].Suspended then Thread[1].Suspend;
if not Thread[2].Suspended then Thread[2].Suspend;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if Thread[1].Suspended then Thread[1].Resume;
if Thread[2].Suspended then Thread[2].Resume;
end;
procedure TForm1.TrackBar2Change(Sender: TObject);
var Priority: TThreadPriority;
i,k: Integer;
begin
k:=(Sender as TTrackBar).Tag;
Priority:=tpIdle;
for i:=0 to ((Sender as TTrackBar).Position-1) do Inc(Priority);
Thread[k].Priority:=Priority;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if (Random<=SpinEdit1.Value/100) and Assigned(Thread[1].e) then
begin
Thread[1].count:=Thread[1].count+1;
Thread[1].e.SetEvent;
Label3.Caption:='Пассажиры - '+IntToStr(Thread[1].count);
end;
if (Random<=SpinEdit2.Value/100) and Assigned(Thread[2].e) then
begin
Thread[2].count:=Thread[2].count+1;
Thread[2].e.SetEvent;
Label4.Caption:='Пассажиры - '+IntToStr(Thread[2].count);
end;
end;
procedure TForm1.SpinEdit3Change(Sender: TObject);
begin
Time:=SpinEdit3.Value;
Timer1.Interval := Time;
end;
end.
Код модулю:
unit Unit2;
interface
uses
Classes, Graphics, ExtCtrls, SyncObjs, SysUtils;
type
TMoveThread = class(TThread)
private
FBox: TPaintBox;
b0, b1: TBitmap;
procedure DoVisualSwap;
procedure DoVisual;
protected
procedure Execute; override;
public
e: TEvent;
i, count: Integer;
constructor Create(a,b: TBitmap; c: TPaintBox);
end;
implementation
uses Unit1;
procedure TMoveThread.Execute;
begin
count:=0;
e:=TEvent.Create(nil, True, False, 'e');
while True do
begin
while i<(FBox.Width+b0.Width) do Synchronize(DoVisualSwap);
if count<=0 then
begin
e.ResetEvent;
e.WaitFor(Form1.Time);
end
else count:=count-1;
while i>=(0-b0.Width) do Synchronize(DoVisual);
end;
e.Free;
end;
procedure TMoveThread.DoVisualSwap;
begin
with FBox do
begin
Canvas.Draw(i,0,b0);
Inc(i);
end;
end;
procedure TMoveThread.DoVisual;
begin
with FBox do
begin
Canvas.Draw(i, 0, b1);
Dec(i);
end;
end;
constructor TMoveThread.Create(a,b: TBitmap; c: TPaintBox);
begin
b0:=a; b1:=b;
FBox:=c;
inherited Create(False);
end;
end.
Запускаем программу (рис.6)
Рис.6
Нажимаем на "Start" (рис.7)
, Рис.7
Нажимам на "Finish"(рис.8)
Рис.8 Задание 4. Семафор Описание задания: имеется несколько, например 10, потоков. Одновременно могут выполняться не все, а только заданное количество потоков, а остальные находятся в состоянии ожидания. Для приостановки всех потоков используется функция Sleep.
Код программы:
unit Prim4;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
ExtCtrls, StdCtrls, ComCtrls, SynCobjs, Spin, Movethds4;
type
TForm1 = class(TForm)
Image1: TImage;
SpinEdit1: TSpinEdit;
SpinEdit2: TSpinEdit;
Label1: TLabel;
Label2: TLabel;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Image2: TImage;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
thread:array[1..10] of TMoveThread;
fsemaphore:THandle;
end;
var
Form1: TForm1;
max_count:byte;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var i:byte;
begin
max_count:=spinedit2.Value;
if button2.Enabled then
begin
for i:=1 to 10 do thread[i].Resume;
button1.Enabled:=false;
button2.Enabled:=true;
end else
begin
fsemaphore:=CreateSemaphore(nil,max_count,{!}10,nil);
for i:=1 to 10 do
begin
thread[i]:=TMoveThread.Create(i, fsemaphore, Image2, Image1);
thread[i].Priority:=tplowest;
end;
button1.Enabled:=false;
button2.Enabled:=true;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var i:byte;
const
s1:string='Остановка потоков';
s2:string='Завершение потоков';
begin
if thread[1].Suspended then
begin
for i:=1 to 10 do
thread[i].Free;
button1.Enabled:=true;
button2.Enabled:=false;
image1.Repaint;
closehandle(fsemaphore);
Button3.Hint:=s1;
end
else
begin
for i:=1 to 10 do
thread[i].Suspend;
button1.Enabled:=true;
button2.Enabled:=true;
Button2.Hint:=s2;
end;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
Sleep(SpinEdit1.Value);
end;
end.
Код модулю:
unit Movethds4;
interface
uses
Sysutils, Windows, Classes, Graphics, ExtCtrls, SynCobjs;
type
{ TMoveThread }
TMoveThread = class(TThread)
private
numb:integer;
FBox,DBox: timage;
h0:thandle;
up:boolean;
procedure DoVisualSwap;
procedure DoVisual;
protected
procedure Execute; override;
public
i: integer;
m: real;
pic:array[0..21] of tbitmap;
constructor Create(num:byte; h:thandle; c:timage; d:timage);
destructor Destroy; override;
end;
implementation
uses Prim4;
{ TMoveThread }
constructor TMoveThread.Create(num:byte;h:thandle;c:timage;d:timage);
begin
numb:=num; h0:=h; Fbox:=c; DBox:=d; i:=0;
inherited Create(False);
end;
destructor TMoveThread.Destroy;
var i:integer;
begin
for i:=Low(Pic) to High(Pic) do
pic[i].free;
inherited Destroy;
end;
procedure TMoveThread.DoVisualSwap;
begin
with FBox do
if up
then canvas.Draw(numb,i,pic[20])
else canvas.Draw(numb,i,pic[21]);
end;
procedure TMoveThread.DoVisual;
begin
with DBox do
begin
canvas.Draw(numb,0,pic[i]);
if i<19 then inc(i) else i:=1;
end;
end;
procedure TMoveThread.Execute;
var
j:byte;
begin
numb:=50*(2*numb-1)-25;
for j:=0 to 19 do
begin
pic[j]:=tbitmap.Create;
if j<8 then pic[j].LoadFromFile('bucket_opened.bmp')
else pic[j].LoadFromFile('bucket_closed.bmp');
end;
pic[20]:=tbitmap.Create;
pic[20].LoadFromFile('drop_up.bmp');
pic[21]:=tbitmap.Create;
pic[21].LoadFromFile('drop_down.bmp');
while true do
begin
while (waitforsingleobject(h0,200)<>WAIT_OBJECT_0) do
begin
if i=7 then i:=1;
Synchronize(DoVisual);
end;
i:=1;
for j:=1 to 7 do Synchronize(DoVisual);
i:=fbox.Height;
up:=true;
while i>pic[1].Height do
begin
Synchronize(DoVisualSwap);
m:=m-0.1;
i:=trunc(m);
end;
up:=false;
while i<fbox.Height do
begin
Synchronize(DoVisualSwap);
m:=m+0.1;
i:=trunc(m);
end;
i:=8;
for j:=8 to 19 do Synchronize(DoVisual);
ReleaseSemaphore(h0,1,nil);
end;
end;
end.
Запуск программы (рис.9)
Рис.9 Ставим время приостановки потока на 2000 и количество потоков на 2 потока (рис.10)
Рис.10
Нажимаем на приостановку потоку (рис.11)
Рис.11 1
Документ
Категория
Рефераты
Просмотров
22
Размер файла
317 Кб
Теги
лаб, отчет
1/--страниц
Пожаловаться на содержимое документа