Створення багатопотокових ужитків

Інформація про навчальний заклад

ВУЗ:
Національний університет Львівська політехніка
Інститут:
Не вказано
Факультет:
Не вказано
Кафедра:
Не вказано

Інформація про роботу

Рік:
2024
Тип роботи:
Лабораторна робота
Предмет:
Delphi

Частина тексту файла (без зображень, графіків і формул):

Створення багатопотокових ужитків Мета роботи: Вивчення можливостей системи програмування Delphi 5 по створенню багатопотокових ужитків. Порядок роботи: Користуючись рекомендованою літературою до лабораторної роботи створити відповідний проект. Змінити текст програми так, щоб він відповідав індивідуальному завданню. Оформити звіт для захисту лабораторної роботи за зразком назва роботи мета роботи порядок роботи короткі теоретичні відомості алгоритм розв’язку задачі тексти відповідних модулів проекту аналіз отриманих результатів та висновки Питання для самоконтролю 1.Що таке потоки? Де вони використовуються? 2.Як створити модуль для опису потоку в Delphi? 3.Описати основні властивості класу TThread. 4.Описати основні методи класу TThread. 5.Як забезпечити синхронну роботу потоків, пов'язаних між собою? Теоретичні відомості Процес - це проста самодостатня програма, яка не викликає інших програм. Процес характеризується своїм адресним простором, віртуальною пам'яттю, виконуваним кодом та даними. В загальному випадку процес може містити декілька потоків. Потік - це певна послідовність команд, в межах одного процесу, якій операційна система виділяє певні кванти часу. Потоки виконуються ніби паралельно. Прикладом багатопотокового ужитку є Microsoft Word, який може одночасно друкувати документ, перевіряти орфографію і реагувати на дії користувача, який редагує текст. Отже, якщо в ужитку є незалежні або частково незалежні одна від одної задачі, то доцільно для кожної з них виділити свій потік. Паралельні потоки працюють в адресному просторі одного процесу і можуть мати доступ до глобальних змінних цього процесу. Для створення ужитку з декількома потоками використовується компонент TThread - абстрактний клас для створення окремого потоку. Для включення компонента TThread у проект Delphi використовується пункт меню File\New\ThreadObject. У відповідному вікні слід ввести ім'я дочірнього класу для TThread, наприклад TMyThread. В результаті створюється новий модуль: unit Unit2; interface uses Classes; type TMyThread = classs (TThread) private protected procedure Execute; override; end; implementation procedure TMyThread.Execute; { основна процедура потоку} begin {код потоку} end; end. Використання потоку завершується по закінченню процедури Execute. Методи класу потоку. constructor Create (CreateSuspended: Boolean) - створення об'єкту потоку. Параметр CreateSuspended задає спосіб виконання потоку. Якщо CreateSuspended = False, то процедура Execute виконується одразу після створення об'єкту. Якщо CreateSuspended = True, то процедура Execute виконується після виконання метода Resume. Процедура Resume окрім цього може запускати потік, зупинений за допомогою метода Suspend. Перевірити, чи потік є зупинений, можна за допомогою властивості Suspended. Якщо у процедурі Execute викликаються методи, або використовуються властивості компонентів VCL, то для уникнення конфлікту між потоками використовується метод Synchronize (Method: ThreadMethod). (Method - це процедура, яка працює з компонентами VCL)/ При цьому код модуля Unit2 зміниться наступним чином. unit Unit2; interface uses Classes; { інші модулі дописує програміст} type TMyThread = classs (TThread) private procedure Work; protected procedure Execute; override; end; implementation procedure TMyThread.Work; begin { код потоку } end; procedure TMyThread.Execute; { основна процедура потоку} begin Synchronize (Work) end; end. Щоб достроково зупинити виконання потоку у процедуру Execute додається перевірка властивості Terminated. Якщо зовнішній потік викликав метод Terminate для цього потоку, то Terminated встановлюється в True. Наприклад: procedure TMyThread.Execute; begin repeat DoSomething until Terminated; end; Щоб негайно завершити потік використовується функція Win32 API TerminateThread (Thread1.Handle, 0), де Thread1.Handle - ім'я потоку, 0 - код завершення, що передається у властивість ReturnValue. По завершенні потоку можливі 2 варіанти: Об'єкт типу TThread руйнується, зі звільненням пам'яті (якщо властивість FreeOnTerminate = True). Об'єкт типу TThread залишається у пам'яті (якщо властивість FreeOnTerminate = False). Тоді для звільнення пам'яті використовується метод Free/ Щоб потік очікував на завершення іншого потоку (наприклад, який готує вхідні дані), використовується метод WaitFor. Якщо потік завершений, то цей метод повертає властивість ReturnValue. Кожен потік має певний рівень пріоритету (властивість Priority): tpIdle (виконується лише, коли система вільна), tpLowest, tpLower, tpNormal, tpHigher, tpHighest, tpTimeCritical (найвищий пріоритет). Завдання Створити проект - модель гри "Рухомий хробак". Переміщення хробака здійснюється в основному модулі, для відображення появи маленьких кульок, які з’їдає хробак, використати окремий потік. Текст Програми: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, Buttons, ComCtrls, StdCtrls, jpeg, Unit2; type TSegment=class(TImage) public Direction:byte; end; TSegments=array of TSegment; type TForm1 = class(TForm) Timer1: TTimer; Image1: TImage; Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; function CreateSegment(Pos:TPoint; Dir:byte):TSegment; procedure AddSegments(Quantity:integer); procedure FormCreate(Sender: TObject); procedure MoveSegments(var Segments:TSegments); procedure ChangeDirection(var Segments:TSegments; Key:Word); procedure Timer1Timer(Sender: TObject); procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); private { Private declarations } public { Public declarations } end; var Form1: TForm1; Snake: TSegments; T1:TMyThread; olddir,newdir,home,n:byte; i:integer; stop:boolean; implementation {$R *.dfm} {$R Data.res} procedure TForm1.AddSegments(Quantity:integer); var i:integer; Pos:TPoint; begin For i:=1 to Quantity do begin SetLength(Snake,Length(Snake)+1); if Length(Snake)=1 then begin Snake[High(Snake)]:=CreateSegment(Point(0,150),3); end else begin Pos:=Point(Snake[High(Snake)-1].left,Snake[High(Snake)-1].Top); case Snake[High(Snake)-1].Direction of 1: Snake[High(Snake)]:= CreateSegment(Point(Pos.X+15,Pos.Y),Snake[High(Snake)-1].Direction); 2: Snake[High(Snake)]:= CreateSegment(Point(Pos.X,Pos.Y+15),Snake[High(Snake)-1].Direction); 3: Snake[High(Snake)]:= CreateSegment(Point(Pos.X-15,Pos.Y),Snake[High(Snake)-1].Direction); 4: Snake[High(Snake)]:= CreateSegment(Point(Pos.X,Pos.Y-15),Snake[High(Snake)-1].Direction); end; end; end; end; procedure TForm1.MoveSegments(var Segments:TSegments); var T1:TMyThread; key:word; i:integer; begin for i:=High(Segments) downto 1 do Segments[i].Direction:=Segments[i-1].Direction; for i:=0 to High(Segments) do begin case Segments[i].Direction of 1: Segments[i].Left:=Segments[i].Left-15; 2: Segments[i].Top:=Segments[i].Top-15; 3: Segments[i].Left:=Segments[i].Left+15; 4: Segments[i].Top:=Segments[i].Top+15; end; end; if OldDir<>NewDir then begin case NewDir of 1: key:=vk_Left; 2: key:=vk_up; 3: key:=vk_right; 4: key:=vk_down; end; changedirection(Segments,key); olddir:=Segments[0].Direction; end; if Edit1.Text='' then else if (Snake[0].Left>= strtoint(Edit1.Text)-10) and (Snake[0].Left<= strtoint(Edit1.Text)+10)and(Snake[0].Top>=strtoint(Edit2.Text)-10) and(Snake[0].Top<=strtoint(Edit2.Text)+10) then begin Edit3.Text:='FFFF'; T1:= TMyThread.Create(false); T1:= TMyThread.Create(true); T1.Priority:=tpLower; T1.Resume; end; if (Snake[0].Top>=Form1.ClientHeight)or(Snake[0].Top<=0)or (Snake[0].Left>=Form1.ClientWidth)or(Snake[0].Left<=0) then begin Timer1.Enabled:=false; for i:=Length(Snake)-1 downto 0 do snake[i].free; Timer1.Enabled:=true; SetLength(Snake,0); AddSegments(2); end; end; function TForm1.CreateSegment(Pos:TPoint; Dir:byte):TSegment; var Segment:TSegment; begin Segment:=TSegment.Create(Self); with Segment do begin Autosize:=true; Transparent:=true; Left:=Pos.X; Top:=Pos.Y; Direction:=Dir; Tag:=1; Picture.Bitmap.LoadFromResourceName(Hinstance,'Segment'); Parent:=Form1; end; Result:=Segment; end; procedure TForm1.ChangeDirection(var Segments:TSegments; Key:Word); begin with Segments[0] do begin if (Key=vk_Left) and (direction=2) then begin Left:=Left-15; Top:=Top+15; Direction:=1; end else if (Key=vk_Left) and (direction=4) then begin Left:=Left-15; Top:=Top-15; Direction:=1; end else if (Key=vk_Right) and (direction=2) then begin Left:=Left+15; Top:=Top+15; Direction:=3; end else if (Key=vk_Right) and (direction=4) then begin Left:=Left+15; Top:=Top-15; Direction:=3; end else if (Key=vk_Down) and (direction=1) then begin Left:=Left+15; Top:=Top+15; Direction:=4; end else if (Key=vk_Down) and (direction=3) then begin Left:=Left-15; Top:=Top+15; Direction:=4; end else if (Key=vk_up) and (direction=1) then begin Left:=Left+15; Top:=Top-15; Direction:=2; end else if (Key=vk_up) and (direction=3) then begin Left:=Left-15; Top:=Top-15; Direction:=2; end; end; end; procedure TForm1.FormCreate(Sender: TObject); begin stop:=false; DoubleBuffered:=True; AddSegments(2); Timer1.Enabled:=true; T1:= TMyThread.Create(true); T1.Priority:=tpLower; T1.Resume; end; procedure TForm1.Timer1Timer(Sender: TObject); begin MoveSegments(Snake); if Length(Snake)>=2 then stop:=false; end; procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); begin case key of vk_left: newdir:=1; vk_right: newdir:=3; vk_up: newdir:=2; vk_down: newdir:=4; end; if (Key=VK_ESCAPE) then Application.Terminate; if (Key=VK_SPACE) then Timer1.Enabled:=not Timer1.Enabled; if (Key=VK_HOME) then begin Timer1.Enabled:=false; for i:=Length(Snake)-1 downto 0 do snake[i].free; Timer1.Enabled:=true; form1.Refresh; SetLength(Snake,0); AddSegments(12); end; if (Key=VK_Shift) then begin Timer1.Enabled:=False; MessageDlg('"Стрілка вгору" - Рух вгору'+#13+ '"Стрілка вниз" - Рух вниз'+#13+ '"Стрілка вліво" - Рух вліво'+#13+ '"Стрілка вправо" - Рух вправо'+#13+ '"Space" - зупинка або продовження руху'+#13+ '"Home" - повернення в початковий стан'+#13+ '"Insert" - Збільшення розмірів'+#13+ '"Delete" - Зменшення розмірів'+#13+ '"F1" - Збільшення швидкості'+#13+ '"F2" - Зменшення швидкості'+#13+ '"Escape" - вихід з програми',mtInformation,[mbOk],0); Timer1.Enabled:=true; end; if (Key=VK_F1) then begin if Timer1.Interval=10 then else Timer1.Interval:=Timer1.Interval-20; end; if (Key=VK_F2) then Timer1.Interval:=Timer1.Interval+20; if (Key=VK_Insert) then AddSegments(1); if (Key=VK_Delete) then begin if stop=false then begin if Length(Snake)=2 then stop:=true; Snake[Length(Snake)-1].Free; SetLength(Snake,Length(Snake)-1); end; end; end; end. unit Unit2; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, Buttons, ComCtrls, StdCtrls, jpeg; type TSegment=class(TImage) public Direction:byte; end; type TMyThread = class(TThread) private procedure Work; Public W:boolean; protected procedure Execute; override; end; var Plus:TSegment; implementation uses Unit1; procedure TMyThread.Work; begin if Form1.Edit3.Text='FFFF' then begin Plus.Free; Form1.Edit3.Text:='' end else begin randomize; Plus:=TSegment.Create(Plus); with Plus do begin Autosize:=true; Transparent:=true; Left:=random(Form1.ClientWidth); Top:=random(Form1.ClientHeight); Tag:=1; Picture.Bitmap.LoadFromResourceName(Hinstance,'Plus'); Parent:=Form1; end; Form1.Edit1.Text:=inttostr(Plus.Left); Form1.Edit2.Text:=inttostr(Plus.Top); end; end; procedure TMyThread.Execute; begin Synchronize (Work); end; end. Висновок: Ми вивчили можливості системи програмування Delphi 5 по створенню багатопотокових ужитків. МІНІСТЕРСВО ОСВІТИ ТА НАУКИ УКРАЇНИ НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ „ЛЬВІВСЬКА ПОЛІТЕХНІКА” Кафедра АСУ Лабораторна робота №10 на тему: „Створення багатопотокових ужитків” Підготував: студент групи КН-310 Мартинюк Р.В. Перевірив: Зварич Р.О. Львів - 2007
Антиботан аватар за замовчуванням

01.01.1970 03:01-

Коментарі

Ви не можете залишити коментар. Для цього, будь ласка, увійдіть або зареєструйтесь.

Ділись своїми роботами та отримуй миттєві бонуси!

Маєш корисні навчальні матеріали, які припадають пилом на твоєму комп'ютері? Розрахункові, лабораторні, практичні чи контрольні роботи — завантажуй їх прямо зараз і одразу отримуй бали на свій рахунок! Заархівуй всі файли в один .zip (до 100 МБ) або завантажуй кожен файл окремо. Внесок у спільноту – це легкий спосіб допомогти іншим та отримати додаткові можливості на сайті. Твої старі роботи можуть приносити тобі нові нагороди!
Нічого не вибрано
0%

Оголошення від адміністратора

Антиботан аватар за замовчуванням

Подякувати Студентському архіву довільною сумою

Admin

26.02.2023 12:38

Дякуємо, що користуєтесь нашим архівом!