close

Вход

Забыли?

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

?

otchyot 3

код для вставкиСкачать
 Министерство образования и науки Российской Федерации
Федеральное государственное бюджетное образовательное учреждение
Высшего профессионального образования "РЯЗАНСКИЙ ГОСУДАРСТВЕННЫЙ РАДИОТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ"
Кафедра ЭВМ
Отчёт по лабораторной работе № "Средства синхронизации потоков и их реализация в среде Delphi"
по курсу "Операционные системы и оболочки"
Выполнил: ст.гр. 142
Анашкин А.Ю.
Проверил:
доцент кафедры ЭВМ
к.т.н Засорин С.В.
Рязань 2013
Задание 1. Критические секции
Описание задания: движение автомобилей воспроизводится в одном компоненте, задача состоит в недопущении ими одновременного использования компонента.
Рисунок 1
Рисунок 2
В результате выполнения задания создано приложение, в котором при старте запускается первый поток, а второй ожидает возникновения события чтобы начаться и занять компонент. После того как второй поток займёт компонент, первый поток будет находиться в ожидании возникновения события, чтобы начаться и занять компонент.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ExtCtrls, SYNCOBJS, MoveThread; type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
pb: TPaintBox;
TrackBar1: TTrackBar;
TrackBar2: TTrackBar;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure TrackBar1Change(Sender: TObject);
procedure TrackBar2Change(Sender: TObject);
private
{ Private declarations }
procedure StartThread(thread: TMoveThread);
procedure StopThread(thread: TMoveThread);
public
{ Public declarations }
taxi00, rtaxi00, taxi01, rtaxi01: TBitmap;
Thread1, Thread2: TMoveThread;
c: TCriticalSection;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
c := TCriticalsection.Create;
taxi00:=tbitmap.Create;
taxi00.LoadFromFile('mashinki mal 21.bmp');
rtaxi00:=tbitmap.Create;
rtaxi00.LoadFromFile('12175869621.bmp');
taxi01:=tbitmap.Create;
taxi01.LoadFromFile('mashinki mal 2.bmp');
rtaxi01:=tbitmap.Create;
rtaxi01.LoadFromFile('1217586962.bmp');
thread1:=TMovethread.Create(taxi00,taxi01, pb);
thread1.Priority:=tplowest;
thread2:=TMovethread.Create(rtaxi00,rtaxi01, pb);
thread2.Priority:=tplowest;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Thread1.Destroy();
Thread2.Destroy();
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
StartThread(Thread1);
StartThread(Thread2);
end;
procedure TForm1.StartThread(thread: TMoveThread);
begin
if thread.Suspended then
thread.Resume;
end;
procedure TForm1.StopThread(thread: TMoveThread);
begin
if not thread.Suspended then
thread.Suspend;
end;
procedure TForm1.TrackBar1Change(Sender: TObject);
Var
I: Integer;
Priority: TThreadPriority;
begin
Priority:=tpLowest;
for i:= 0 to TrackBar1.Position - 1 do
inc(Priority);
Thread1.Priority:=Priority
end;
procedure TForm1.TrackBar2Change(Sender: TObject);
Var
I: Integer;
Priority: TThreadPriority;
begin
Priority:=tpLowest;
for i:= 0 to TrackBar1.Position - 1 do
inc(Priority);
Thread1.Priority:=Priority
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
StopThread(Thread1);
StopThread(Thread2);
end;
end.
unit MoveThread;
interface
uses
Graphics, ExtCtrls, Classes, SysUtils;
type
TMoveThread = class(TThread)
private
FBox: TPaintBox;
b0,b1: tbitmap;
i: integer;
procedure DoVisualSwap;
procedure DoVisual;
protected
procedure Execute; override;
procedure Delay(delay:integer);
public
constructor Create(a,b: TBitmap; c:TPaintBox);
destructor Destroy();
end;
implementation
uses Unit1;
constructor TMoveThread.Create(a,b:tbitmap; c:TPaintBox);
begin
b0:=a;b1:=b;Fbox:=c;i:=0;
inherited Create(False);
end;
destructor TMoveThread.Destroy();
begin
b0.Free;
b1.Free;
end;
procedure TMoveThread.Execute;
begin
while true do
begin
Form1.c.Enter;
Sleep(4);
try
while i<=(fbox.Width+b0.Width) do
begin
Sleep(4);
Synchronize(DoVisualSwap);
end;
finally Form1.c.Leave;
end;
Sleep(4);
Form1.c.Enter;
Sleep(4);
try
while i>=(0-b0.Width) do
begin
Sleep(4);
Synchronize(DoVisual);
end;
finally Form1.c.Leave;
end;
Sleep(4);
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;
procedure TMoveThread.Delay(delay:integer);
var
i,j :Integer;
begin
for j := 0 to delay - 1 do
for i:=1 to delay do
begin
end;
end;
end.
Задание 2. Объект Mutex
Описание задания: Движение автомобилей воспроизводится в одном компоненте, задача состоит в появлении второго автомобиля только через определенный интервал времени после первого.
При малой задержке расстояние между автомобилями практически не изменяется:
Рисунок 4
С увеличением задержки увеличивается расстояние.
Рисунок 5
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, Spin, IPCThrd, UMoveThread;
type
TForm1 = class(TForm)
PaintBox1: TPaintBox;
Button1: TButton;
Button2: TButton;
SpinEdit: TSpinEdit;
lbl: TLabel;
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
taxi00, rtaxi00, taxi01, rtaxi01: TBitmap;
Thread1, Thread2: TMoveThread;
procedure StartThread(thread: TMoveThread);
procedure StopThread(thread: TMoveThread);
public
{ Public declarations }
m: TMutex;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
Thread1.Destroy();
Thread2.Destroy();
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
m := TMutex.Create('mutex');
taxi00:=tbitmap.Create;
taxi00.LoadFromFile('mcar00.bmp');
rtaxi00:=tbitmap.Create;
rtaxi00.LoadFromFile('mcar01.bmp');
taxi01:=tbitmap.Create;
taxi01.LoadFromFile('zapr.bmp');
rtaxi01:=tbitmap.Create;
rtaxi01.LoadFromFile('zapr2.bmp');
thread1:=TMovethread.Create(taxi00,taxi01, PaintBox1);
thread1.Priority:=tplowest;
thread2:=TMovethread.Create(rtaxi00,rtaxi01, PaintBox1);
thread2.Priority:=tplowest;
end;
procedure TForm1.StartThread(thread: TMoveThread);
begin
end;
procedure TForm1.StopThread(thread: TMoveThread);
begin
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if thread1.Suspended then
thread1.Resume;
if thread2.Suspended then
thread2.Resume;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if not thread1.Suspended then
thread1.Suspend;
if not thread2.Suspended then
thread2.Suspend;
end;
end.
unit UMoveThread;
interface
uses
Graphics, ExtCtrls, Classes, 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);
destructor Destroy();
end;
implementation
uses
Unit1;
constructor TMoveThread.Create(a,b:tbitmap; c:TPaintBox);
begin
b0:=a;b1:=b;Fbox:=c;i:=0;
inherited Create(False);
end;
destructor TMoveThread.Destroy();
begin
b0.Free;
b1.Free;
end;
procedure TMoveThread.Execute;
begin
while true do
begin
Form1.m.Get(Form1.SpinEdit.Value);
try
while i<=(fbox.Width+b0.Width) do
Synchronize(DoVisualSwap);
finally Form1.m.Release;
end;
Form1.m.Get(Form1.SpinEdit.Value);
try
while i>=(0-b0.Width) do
Synchronize(DoVisual);
finally Form1.m.Release;
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;
end.
Задание 3. Событие
Описание задания. Автомобили перевозят пассажиров. Задача состоит в недопущении поездок автомобиля без пассажиров. В этом задании создается приложение, в котором случайным образом наступает событие - появление пассажира. Автомобили могут перевозить пассажиров с определенной скоростью. При запуске приложения потоки ждут возникновения события. Когда событие возникает, увеличивается количество пассажиров и автомобили начинают движение.
Рисунок 6
Рисунок 7
Когда количество пассажиров равно нулю, то автомобили прекращают движение.
Рисунок 8
Чем больше вероятность возникновения события, тем больше вероятность движения автомобиля.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Spin, ExtCtrls, UMoveThread;
type
TForm1 = class(TForm)
PaintBox1: TPaintBox;
PaintBox2: TPaintBox;
Button1: TButton;
Button2: TButton;
SpinEdit1: TSpinEdit;
SpinEdit2: TSpinEdit;
tmr1: TTimer;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
lblcount1: TLabel;
lblcount2: TLabel;
procedure TimerTimer(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure buton1Click(Sender: TObject);
procedure button2Click(Sender: TObject);
private
{ Private declarations }
taxi00, rtaxi00, taxi01, rtaxi01: TBitmap;
Thread1, Thread2: TMoveThread;
procedure StartThread(thread: TMoveThread);
procedure StopThread(thread: TMoveThread);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
taxi00:=tbitmap.Create;
taxi00.LoadFromFile('7.bmp');
rtaxi00:=tbitmap.Create;
rtaxi00.LoadFromFile('5.bmp');
taxi01:=tbitmap.Create;
taxi01.LoadFromFile('6.bmp');
rtaxi01:=tbitmap.Create;
rtaxi01.LoadFromFile('8.bmp');
thread1:=TMovethread.Create(taxi00,taxi01, PaintBox1);
thread1.Priority:=tplowest;
thread2:=TMovethread.Create(rtaxi00,rtaxi01, PaintBox2);
thread2.Priority:=tplowest;
end;
procedure TForm1.TimerTimer(Sender: TObject);
begin
if (random<=SpinEdit1.Value/100) then
begin
thread1.count:=thread1.count+1;
thread1.e.SetEvent;
end;
if (random<=SpinEdit2.Value/100) then
begin
thread2.count:=thread2.count+1;
thread2.e.SetEvent;
end;
lblCount1.Caption := IntToStr(thread1.count);
lblCount2.Caption := IntToStr(thread2.count);
end;
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
Thread1.Destroy();
Thread2.Destroy();
end;
procedure TForm1.buton1Click(Sender: TObject);
begin
StartThread(Thread1);
StartThread(Thread2);
end;
procedure TForm1.StartThread(thread: TMoveThread);
begin
if Thread.Suspended then
Thread.Resume;
end;
procedure TForm1.StopThread(thread: TMoveThread);
begin
if not thread.Suspended then
thread.Suspend;
end;
procedure TForm1.button2Click(Sender: TObject);
begin
StopThread(Thread1);
StopThread(Thread2);
end;
end.
Unit UMoveThread;
interface
uses
Graphics, ExtCtrls, Classes, SysUtils, SYNCOBJS;
type
TMoveThread = class(TThread)
private
FBox: TPaintBox;
b0,b1: tbitmap;
i: integer;
procedure DoVisualSwap;
procedure DoVisual;
protected
procedure Execute; override;
procedure Delay(delay:integer);
public
e: TEvent;
count: integer;
constructor Create(a,b: TBitmap; c:TPaintBox);
destructor Destroy();
end;
implementation
uses
Unit1;
constructor TMoveThread.Create(a,b:tbitmap; c:TPaintBox);
begin
b0:=a;b1:=b;Fbox:=c;i:=0;
inherited Create(False);
end;
destructor TMoveThread.Destroy();
begin
e.Free;
b0.Free;
b1.Free;
end;
procedure TMovethread.Execute;
begin
count:=0;
e:=tevent.create(nil,True,false,'e');
while true do
begin
while (i<=(fbox.Width+b0.Width)) and (count > 0) do
begin
Sleep(4);
Synchronize(DoVisualSwap);
end;
if count<=0 then
begin
e.ResetEvent;
e.WaitFor(100000);
end
else
begin
count:=count-1;
end;
while (i>=(0-b0.Width)) and (count > 0) do
begin
Sleep(4);
Synchronize(DoVisual);
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;
procedure TMoveThread.Delay(delay:integer);
var
i,j :Integer;
begin
for j := 0 to delay - 1 do
for i:=1 to delay do
begin
end;
end;
end.
Задание 4. Семафор Описание задания: имеется несколько, например 10, потоков. Одновременно могут выполняться не все, а только заданное количество потоков, а остальные находятся в состоянии ожидания. Для приостановки всех потоков используется функция Sleep. Рисунок 9
Рисунок 10
Рисунок 11
Семафор подобен взаимному исключению. Разница между ними в том, что семафор может управлять количеством потоков, которые имеют к нему доступ. Семафор устанавливается на предельное число потоков, которым доступ разрешен. Когда это число достигнуто, последующие потоки будут приостановлены, пока один или более потоков не отсоединятся от семафора и не освободят доступ.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Spin, ExtCtrls, UMoveThread;
type
TForm1 = class(TForm)
pb1: TPaintBox;
pb2: TPaintBox;
pb3: TPaintBox;
pb4: TPaintBox;
pb5: TPaintBox;
pb6: TPaintBox;
pb7: TPaintBox;
pb8: TPaintBox;
pb9: TPaintBox;
pb10: TPaintBox;
Button1: TButton;
Button2: TButton;
Button3: TButton;
secount: TSpinEdit;
setime: TSpinEdit;
Label1: TLabel;
Label2: TLabel;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
procedure EnabledControls(isEnabled: Boolean);
public
{ Public declarations }
thread:array[1..10] of TMoveThread;
fsemaphore:THandle;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button2Click(Sender: TObject);
var
i:byte;
begin
for i:=1 to 10 do
thread[i].Suspend;
for i:=1 to 10 do
thread[i].Destroy;
EnabledControls(True);
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
Sleep(seTime.Value*1000);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i:byte;
canvasList: TList;
begin
fsemaphore:=CreateSemaphore(nil,seCount.Value, 10, nil);
canvasList := TList.Create;
canvasList.Add(pb1);
canvasList.Add(pb2);
canvasList.Add(pb3);
canvasList.Add(pb4);
canvasList.Add(pb5);
canvasList.Add(pb6);
canvasList.Add(pb7);
canvasList.Add(pb8);
canvasList.Add(pb9);
canvasList.Add(pb10);
for i:=1 to 10 do
begin
thread[i]:=TMoveThread.Create(fsemaphore, TPaintBox(canvasList[i-1]));
thread[i].Priority:=tplowest;
end;
EnabledControls(false);
end;
procedure TForm1.EnabledControls(isEnabled: Boolean);
begin
Button1.Enabled := isEnabled;
seCount.Enabled := isEnabled;
Button2.Enabled := not isEnabled;
end;
end.
unit UMoveThread;
interface
uses
Sysutils, Windows, Classes, Graphics, ExtCtrls, SynCobjs;
type
{ TMoveThread }
TMoveThread = class(TThread)
private
pb: TPaintBox;
h:thandle;
coordinates: Integer;
imgDrop, imgBucket: TBitmap;
procedure DoVisualSwap;
procedure DoVisual;
protected
procedure Execute; override;
procedure DrawBucket;
procedure ClearCanvas;
public
sleepTime: Integer;
constructor Create(h: thandle; pb: TPaintBox);
destructor Destroy; override;
end;
implementation
uses Unit1;
{ TMoveThread }
constructor TMoveThread.Create(h: thandle; pb:TPaintBox);
begin
imgDrop := tbitmap.Create;
imgBucket := tbitmap.Create;
Self.h := h;
Self.pb := pb;
ClearCanvas;
sleepTime:= 5;
imgBucket.LoadFromFile('418.bmp');
DrawBucket;
inherited Create(False);
end;
destructor TMoveThread.Destroy;
begin
ClearCanvas;
imgDrop.Free;
imgBucket.Free;
end;
procedure TMoveThread.ClearCanvas;
begin
pb.Canvas.Brush.Color := clWhite;
pb.Canvas.FillRect(Rect(0,0,pb.Width,pb.Height));
end;
procedure TMoveThread.DrawBucket;
begin
pb.canvas.Draw(0, pb.Height-30, imgBucket);
end;
procedure TMoveThread.DoVisualSwap;
begin
pb.canvas.Draw(0, coordinates, imgDrop);
DrawBucket;
inc(coordinates);
end;
procedure TMoveThread.DoVisual;
begin
pb.canvas.Draw(0,coordinates,imgDrop);
DrawBucket;
dec(coordinates);
end;
procedure TMoveThread.Execute;
begin
coordinates := pb.Height;
while true do
begin
while (waitforsingleobject(Form1.fsemaphore,200)<>WAIT_OBJECT_0) do
begin
Sleep(sleepTime);
end;
imgBucket.LoadFromFile('410.bmp');
imgDrop.LoadFromFile('kaplya.bmp');
while coordinates>=0 do
begin
Sleep(sleepTime);
Synchronize(DoVisual);
dec(coordinates);
end;
imgDrop.LoadFromFile('kaplyaup.bmp');
while coordinates<=pb.Height do
begin
Sleep(sleepTime);
Synchronize(DoVisualSwap);
inc(coordinates);
end;
imgBucket.LoadFromFile('418.bmp');
DrawBucket;
Sleep(sleepTime*4);
ReleaseSemaphore(h,1,nil);
end;
end;
end.
20
Документ
Категория
Рефераты
Просмотров
19
Размер файла
431 Кб
Теги
лабораторная работа, otchyot, лаба, лабораторная
1/--страниц
Пожаловаться на содержимое документа