МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
ЛАБОРАТОРНА РОБОТА № 1
з курсу “Комп’ютерні методи дослідження систем керування”
Створення WIN32-програм з розділеними
паралельно в часі математичними обчисленнями
Львів 2009
Мета роботи
Отримати навики роботи в системі візуального об’єктно-орієнтованого програмування C++Builder та освоїти розроблення програм орієнтованих на виконання складних математичних розрахунків з розділенням їх виконання паралельно в часі.
Завдання до лабораторної роботи.
1.Вдома детально вивчити поданий у інструкції довідковий матеріал до лабораторної роботи.
2.У навчальній лабораторії в присутності викладача виконати практичне заняття № 1. Практичні заняття № 2 та № 3 виносяться на самостійне опрацювання студентами.
3.Згідно варіанту (порядкового номера в журналі викладача) завдання (таблиця 1), вдома написати програмний код для обчислення математичного виразу в окремо створеному потоці програми, а в лабораторії спроектувати та налагодити цю програму.
4.По результатах виконаної роботи оформити звіт та здати його.
Таблиця 1. Завдання до лабораторної роботи
№
п/п
Створення потоку засобами
Вивід результатів
Протабулювати функцію
(50 інтервалів)
9
компоненти типу TThread
на форму програми
Короткі теоретичні відомості, що необхідні для виконання лабораторної роботи.
Основною рисою сучасних операційних систем є багатозадачність. Кожній програмі системою періодично виділяється квант часу, протягом якого вона виконує свою ділянку коду. Не зважаючи на стан програми, після закінчення цього кванту система забирає керування від програми та передає його іншій програмі. Якщо програма зависла, то система від цього не постраждає. Керування в будь-якому випадку буде передано іншій програмі.
В операційній системі Windows реалізовані два види багатозадачності – процесна та потокова. Процес (Process) – це статичний об’єкт (програма), який не виконується, а попросту «володіє» виділеним йому адресним простором, іншими словами, процес є структурою в пам’яті. Випадок, при якому програма може вирватися із рамок свого процесу та пошкодити чужі ресурси, є практично неможливим. В адресному просторі процесу знаходяться не тільки код та дані, але й потоки (Thread) – об’єкти, що виконується. Саме потокам операційна система виділяє кванти часу, а не процесам. При запуску процесу автоматично запускається потік (який називається головним). При зупинці головного потоку автоматично зупиняється і процес. А так як процес без потоку попросту займає ресурси, то система автоматично знищує його. Поряд із первинним потоком можуть у процесі існувати й додаткові потоки, яким система виділятиме окремі кванти часу. Такий багатопотоковий підхід дає можливість в межах однієї програми здійснювати різні задачі: робота з портами, файлами, математичні обчислення тощо. Наприклад, програма Microsoft Word може одночасно корегувати граматику та друкувати, при цьому здійснюючи ввід даних з клавіатури.
Зупинимося на одній деталі. На однопроцесорному комп’ютерові в кожний конкретний момент часу виконується одна задача. Якщо при запуску двох-трьох невеликих програм часова затримка суб’єктно не помітна, то при запуску декількох програм, що потребують колосальних ресурсів, затримка при виконанні програм стає достатньо помітною. На багатопроцесорних системах за кожним процесором може бути закріплений свій потік, і тому на таких системах виконання програм здійснюється дійсно в багатозадачному режимі.
На основі програмного пакету C++Builder потокова багатозадачність може бути реалізована:
з використанням компоненти типу TThread;
засобами інтерфейсу WIN32 API.
Список ідентифікаторів констант, змінних, функцій, методів, використаних у програмі, та їх пояснення.
СПИСОК :
A
B
X
Y
H
ПОЯСНЕННЯ ІДЕНТИФІКАТОРІВ ЗМІННИХ :
Y – значення функції
X – значення аргументу
A – ліва крайня межа табулювання
B – права крайня межа табулювання
H – крок табулювання функції
ПОЯСНЕННЯ ІДЕНТИФІКАТОРІВ ФУНКЦІЙ :
EndCalculation( ) – Функція що оголошує завершення потоку
Calculation ( ) – Функція виводу значень обчислень на форму мемо.
potic1 ( ) – Функція для виконання обчислень по табулюванню функції
Остаточна версія програми.
Файл Unit1.cpp
//---------------------------------------------------------------------------
#include "Unit2.h"
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
potic1 *pp1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
pp1=new potic1(false);
pp1->FreeOnTerminate = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
if(Button2->Tag==1)
{ pp1->Resume(); Button2->Tag=0; }
else
{ pp1->Suspend(); Button2->Tag=1; }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
Close();
}
Файл Unit2.cpp
//---------------------------------------------------------------------------
#include "Unit1.h"
#include <vcl.h>
#pragma hdrstop
#include "Unit2.h"
#include "Math.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// Important: Methods and properties of objects in VCL can only be
// used in a method called using Synchronize, for example:
//
// Synchronize(UpdateCaption);
//
// where UpdateCaption could look like:
//
// void __fastcall potic1::UpdateCaption()
// {
// Form1->Caption = "Updated in a thread";
// }
//---------------------------------------------------------------------------
__fastcall potic1::potic1(bool CreateSuspended)
: TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------------
void __fastcall potic1::Execute()
{
h=3.98;
a=1;
x=a;
b=200;
while (x<=b) {y=70*(cos(x),3)+20*cos(x/3);
Synchronize(Calculation);x=x+h;};
Synchronize(EndCalculation);
}
//---------------------------------------------------------------------------
void __fastcall potic1::Calculation(void)
{
Form1->Memo1->Lines->Add(AnsiString("Значення функції Y : ")
+AnsiString("Значення аргументу X : "));
Form1->Memo1->Lines->Add(" ");
Form1->Memo1->Lines->Add(AnsiString(y)+
AnsiString(" ")+AnsiString(x));
Form1->Memo1->Lines->Add(" ");
}
void __fastcall potic1::EndCalculation(void)
{
y=70*(cos(x),3)+20*cos(x/3);
Form1->Memo1->Lines->Add(AnsiString(y)+
AnsiString(" ")+AnsiString(x));
Form1->Memo1->Lines->Add(" ");
Form1->Memo1->Lines->Add("обчислення всередині потоку завершено");
}
Файл Unit1.h
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
TButton *Button2;
TMemo *Memo1;
TButton *Button3;
void __fastcall Button1Click(TObject *Sender);
void __fastcall Button2Click(TObject *Sender);
void __fastcall Button3Click(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Файл Unit2.h
//---------------------------------------------------------------------------
#ifndef Unit2H
#define Unit2H
//---------------------------------------------------------------------------
#include <Classes.hpp>
//---------------------------------------------------------------------------
class potic1 : public TThread
{
private:
protected:
void __fastcall Execute();
public:
__fastcall potic1(bool CreateSuspended);
void __fastcall Calculation(void);
void __fastcall EndCalculation(void);
int count;
double x,y,a,h,b;
};
//---------------------------------------------------------------------------
#endif
Результати виконання програми.
Значення функції Y : Значення аргументу X :
228,899138926295 1
Значення функції Y : Значення аргументу X :
208,218291661271 4,98
Значення функції Y : Значення аргументу X :
190,239540915715 8,96
Значення функції Y : Значення аргументу X :
202,229032757395 12,94
Значення функції Y : Значення аргументу X :
226,003788821456 16,92
Значення функції Y : Значення аргументу X :
225,507579131604 20,9
Значення функції Y : Значення аргументу X :
201,492943509722 24,88
Значення функції Y : Значення аргументу X :
190,379907568119 28,86
Значення функції Y : Значення аргументу X :
209,022237484903 32,84
Значення функції Y : Значення аргументу X :
229,147418792951 36,82
Значення функції Y : Значення аргументу X :
220,234079849063 40,8
Значення функції Y : Значення аргументу X :
195,799978646278 44,78
Значення функції Y : Значення аргументу X :
192,901292327183 48,76
Значення функції Y : Значення аргументу X :
215,93409966831 52,74
Значення функції Y : Значення аргументу X :
229,967392492177 56,72
Значення функції Y : Значення аргументу X :
213,718612440723 60,7
Значення функції Y : Значення аргументу X :
191,830273144407 64,68
Значення функції Y : Значення аргументу X :
197,497709745285 68,66
Значення функції Y : Значення аргументу X :
222,125822596205 72,64
Значення функції Y : Значення аргументу X :
228,364201100222 76,62
Значення функції Y : Значення аргументу X :
206,75186868984 80,6
Значення функції Y : Значення аргументу X :
190,065575023947 84,58
Значення функції Y : Значення аргументу X :
203,611356481982 88,56
Значення функції Y : Значення аргументу X :
226,846002856298 92,54
Значення функції Y : Значення аргументу X :
224,532401688921 96,52
Значення функції Y : Значення аргументу X :
200,179305521395 100,5
Значення функції Y : Значення аргументу X :
190,720041185136 104,48
Значення функції Y : Значення аргументу X :
210,500304147879 108,46
Значення функції Y : Значення аргументу X :
229,521817731011 112,44
Значення функції Y : Значення аргументу X :
218,937006531335 116,42
Значення функції Y : Значення аргументу X :
194,798543638022 120,4
Значення функції Y : Значення аргументу X :
193,714248160148 124,38
Значення функції Y : Значення аргументу X :
217,328536848283 128,36
Значення функції Y : Значення аргументу X :
229,828540734528 132,34
Значення функції Y : Значення аргументу X :
212,25705102092 136,32
Значення функції Y : Значення аргументу X :
191,26257137382 140,3
Значення функції Y : Значення аргументу X :
198,684830636239 144,28
Значення функції Y : Значення аргументу X :
223,267406820572 148,26
Значення функції Y : Значення аргументу X :
227,728949156119 152,24
Значення функції Y : Значення аргументу X :
205,303188577237 156,22
Значення функції Y : Значення аргументу X :
190,000500569872 160,2
Значення функції Y : Значення аргументу X :
205,028578056817 164,18
Значення функції Y : Значення аргументу X :
227,596195903697 168,16
Значення функції Y : Значення аргументу X :
223,477841263537 172,14
Значення функції Y : Значення аргументу X :
198,919312899926 176,12
Значення функції Y : Значення аргументу X :
191,165491230218 180,1
Значення функції Y : Значення аргументу X :
211,975637908448 184,08
Значення функції Y : Значення аргументу X :
229,789579091028 188,06
Значення функції Y : Значення аргументу X :
217,59111497626 192,04
Значення функції Y : Значення аргументу X :
193,880146311581 196,02
Значення функції Y : Значення аргументу X :
194,61616461946 200
обчислення всередині потоку завершено
Висновки.
Беззаперечно, можливість реалізації багатозадачності з використанням компоненти типу TThread дає можливість значно підвищити стабільність роботи програми а також контролювати процес розрахунку даних з можливістю його зупинки та поновлення у будь-який момент часу.