|
Министерство образования и науки Российской Федерации Федеральное государственное бюджетное образовательное учреждение Высшего профессионального образования «РЯЗАНСКИЙ ГОСУДАРСТВЕННЫЙ РАДИОТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ» Кафедра ЭВМ Отчёт по лабораторной работе № «Средства синхронизации потоков и их реализация в среде Delphi» по курсу «Операционные системы и оболочки» Выполнил: ст.гр. 142 Анашкин А.Ю. Проверил: доцент кафедры ЭВМ к.т.н Засорин С.В. Рязань 2013 ^ Описание задания: движение автомобилей воспроизводится в одном компоненте, задача состоит в недопущении ими одновременного использования компонента. ![]() Рисунок ![]() Рисунок 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. ^ Описание задания: Движение автомобилей воспроизводится в одном компоненте, задача состоит в появлении второго автомобиля только через определенный интервал времени после первого. При малой задержке расстояние между автомобилями практически не изменяется: ![]() Рисунок С увеличением задержки увеличивается расстояние. ![]() Рисунок 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. ^ Описание задания. Автомобили перевозят пассажиров. Задача состоит в недопущении поездок автомобиля без пассажиров. В этом задании создается приложение, в котором случайным образом наступает событие - появление пассажира. Автомобили могут перевозить пассажиров с определенной скоростью. При запуске приложения потоки ждут возникновения события. Когда событие возникает, увеличивается количество пассажиров и автомобили начинают движение. ![]() Рисунок ![]() Рисунок Когда количество пассажиров равно нулю, то автомобили прекращают движение. ![]() Рисунок Чем больше вероятность возникновения события, тем больше вероятность движения автомобиля. 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. ^ ; 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. ^ Описание задания: имеется несколько, например 10, потоков. Одновременно могут выполняться не все, а только заданное количество потоков, а остальные находятся в состоянии ожидания. Для приостановки всех потоков используется функция Sleep. ![]() Рисунок ![]() Рисунок ![]() Рисунок Семафор подобен взаимному исключению. Разница между ними в том, что семафор может управлять количеством потоков, которые имеют к нему доступ. Семафор устанавливается на предельное число потоков, которым доступ разрешен. Когда это число достигнуто, последующие потоки будут приостановлены, пока один или более потоков не отсоединятся от семафора и не освободят доступ. 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. |
![]() | Лекция №3 Дисциплина: Мировая финансовая среда. Тема занятия: Движение потоков капитала в мировой финансовой среде Цель занятия: в ходе лекции дать студентам знания относительно сущности, формы, принципов, характерных предпосылок, факторов, направлений... | ![]() | Лекция №2 Дисциплина: Мировая финансовая среда. Тема занятия: Движение потоков капитала в мировой финансовой среде Цель занятия: в ходе лекции дать студентам знания относительно сущности, формы, принципов, характерных предпосылок, факторов, направлений... |
![]() | Урок №13. Тема: Мова програмування Delphi та інтегроване середовище візуальної розробки проектів Turbo Delphi 2006. Принципи роботи у візуальному середовищі розробки програм. Вікно середовища Turbo Delphi 2006 Тапи розв’язування задач з використанням комп’ютера. Подати новий навчальний матеріал про мову програмування Delphi та інтегроване... | ![]() | Лекция 2 «Многопоточное программирование в языке C Пространство имен System. Threading. Класс Thread. Создание потока. Использование нескольких потоков. Планирование потоков, приоритеты... |
![]() | Практическая реализация перспективных схем генетического поиска в инструментальной среде «gensearch» | ![]() | 6. Лекция: Механизмы синхронизации Для повышения производительности вычислительных систем и облегчения задачи программистов существуют специальные механизмы синхронизации.... |
![]() | Лекция Структура языка sql. Типы данных В языке отсутствовали средства синхронизации доступа к объектам бд со стороны параллельно выполняемых транзакций: с самого начала... | ![]() | Оборотные средства предприятия ОбПФ)– средства, находящиеся в сфере производства; фонды обращения (ФО) – средства, находящиеся в сфере обращения. Они образуют оборотные... |
![]() | Планирование денежных потоков Одна из главных проблем любого нового бизнеса — правильное планирование денежных потоков. Даже рентабельные предприятия терпят банкротство... | ![]() | Лекция 1 обеспечение качества программного средства Обеспечение эффективности программного средства. Обеспечение сопровождаемости и управление конфигурацией программного средства. Аппаратно-операционные... |