Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Архив1 / docx54 / Курсовая работа - Силина.docx
Скачиваний:
64
Добавлен:
01.08.2013
Размер:
155.16 Кб
Скачать

3. Структура разработанной программы

3.1 Модульная схема

Описание основных модулей (подпрограмм)

T1Rotate – движение первого поезда по окружности;

T2Rotate – движение второго поезда по окружности;

Timer1Timer – проверка занятости семафоров и, при необходимости, изменение их состояния;

Paint – перерисовка всех примитивов на форме;

4. Результаты тестирования программы

Начальное состояние программы

Поезда в движении после запуска

Первый поезд ждёт проезда второго

Второй поезд ждёт проезда первого

Заключение

Синхронизация потоков - это обобщенный термин, относящийся к процессу взаимодействия и взаимосвязи потоков. Синхронизация потоков требует привлечения в качестве посредника самой операционной системы. Потоки не могут взаимодействовать друг с другом без ее участия.

Правильная синхронизация доступа к ресурсам, общедоступным множеству потоков - один из самых важных аспектов многопоточного программирования. Отсутствие или недостаточная синхронизация приведут к непредсказуемым результатам, и в самом худшем случае - аварийном отказе приложения.

В то же самое время, слишком сложная или ненадлежащим образом используемая синхронизация заставляет потоки тратить слишком много времени, блокируя и таким образом значительно сокращая выгоду многопоточности.

Результатом курсовой работы стала программа, которая регулирует движение поездов через перекрёстки при помощи семафоров. Эту задачу можно решить и иным способом, используя мьютексы, так как семафоры предполагают хоть и ограниченные, но не единичные ресурсы, а в данной задаче по каждому перекрёстку (через каждый семафор) может проезжать только один из существующих поездов.

Для разработки приложения использовались функции Win32 API, содержащиеся в модуле Windows.

Использованная литература

  1. Таненбаум Э. Современные операционные системы. 2-е изд. – СПБ.:Питер, 2002. – 1040 с., ил.

  1. Рихтер Дж. Windows для профессионалов: создание эффективных Win32 приложений с учетом специфики 64-разрядной версии Windows/Пер, англ - 4-е изд. - СПб; Питер; М.: Издательско-торговый дом "Русская Редакция", 2001. - 752 с.; ил.

  2. Михелев В.М. Курс лекций по ОС

  1. Михелёв В.М. Задания к лабораторным работам №2, №3

Приложение

unit Kurs_Os;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

OpenGL, Menus, ExtCtrls, StdCtrls, ComCtrls,

XPMan, Spin, Buttons, ImgList, uTrainParams;

const

sColor: array [0..3] of GLfloat = (1, 0.75, 0, 1);

black: array [0..3] of GLfloat = (0, 0, 0, 1);

type

TForm1 = class(TForm)

Timer1: TTimer;

bbExit: TBitBtn;

procedure FormCreate(Sender: TObject);

procedure FormDestroy(Sender: TObject);

procedure FormResize(Sender: TObject);

procedure FormPaint(Sender: TObject);

procedure MakeVan;

procedure Timer1Timer(Sender: TObject);

procedure bbExitClick(Sender: TObject);

procedure FormClick(Sender: TObject);

private

DC : HDC;

hrc: HGLRC;

quadObj : GLUquadricObj;

public

end;

TState =(tMoving, tWaiting);

var

Form1: TForm1;

tm1, tm2 : integer;

T1 : Real = -1;//127.6;

T2 : Real = 180;

vnorm : GLdouble;

pos : Array [0..3] of GLFloat;

hSemaphore1, hSemaphore2 : THandle;

implementation

{$R *.dfm}

//--------------- Движение левого поезда ----------------

procedure T1Rotate (f: boolean);

begin

if not f then begin

T1 := (T1 - 0.1*tSpeed1);

If T1 < -360 then T1 := 0;

end;

end;

//--------------- Движение правого поезда ----------------

procedure T2Rotate (f: boolean);

begin

if not f then begin

T2 := (T2 + 0.1*tSpeed2);

If T2 > 540 then T2 := 180;

end;

end;

//--------------- Прорисовка вагона ---------------

procedure TForm1.MakeVan;

begin

glBegin(GL_QUADS);

glNormal3f(0,-1,0);

glvertex3f(-0.5,-0.2,-1.0);

glvertex3f(-0.5,-0.2,1.0);

glvertex3f(0.5,-0.2,1.0);

glvertex3f(0.5,-0.2,-1.0);

glEnd;

end;

procedure TForm1.Timer1Timer(Sender: TObject);

procedure S1Train1;

begin

hSemaphore1 := CreateSemaphore(nil,1,1,'MySemaphore1');

f1 := false;

f2:= true;

if (T1>-135) then ReleaseSemaphore(hSemaphore1,1,nil);

case WaitForSingleObject(hSemaphore1, 0)of

Wait_Object_0:

begin

f2:=false;

end;

end;

end;

var sa: SECURITY_ATTRIBUTES;

begin

sa.nLength := sizeof(sa);

sa.lpSecurityDescriptor:= nil;

sa.bInheritHandle := TRUE;

tm1 := (tm1 + 1) mod 360;

T1rotate(f1);

T2rotate(f2);

//----- 1й семафор для левого поезда

if (T1<-125)and(T1>-125-tLength1) then

begin

hSemaphore1 := CreateSemaphore(@sa,1,1,'MySemaphore1');

f1 := false;

if abs(305-T2) < 20 then f2:= true

else f2:=false;

end

else

begin

ReleaseSemaphore(hSemaphore1,1,nil);

if abs(305-T2) < 20 then

case WaitForSingleObject(hSemaphore1, 0)of

Wait_Object_0:

begin

f2:=false;

end;

end;

end;

//----- 2й семафор для левого поезда

if (T1<-185)and(T1>-185-tLength1) then

begin

hSemaphore2 := CreateSemaphore(@sa,1,1,'MySemaphore2');

f1 := false;

if abs(305-T2) < 20 then f2:= true

else f2:=false;

end

else

begin

ReleaseSemaphore(hSemaphore2,1,nil);

if abs(305-T2) < 20 then

case WaitForSingleObject(hSemaphore2, 0)of

Wait_Object_0:

begin

f2:=false;

end;

end;

end;

//----- 1й семафор для правого поезда

if (T2>305)and(T2<305+tLength2){and(tlength2<>20)} then

begin

hSemaphore1 := CreateSemaphore(@sa,1,1,'MySemaphore1');

f2 := false;

if abs(-T1-125) < 20 then f1:= true

else f1:=false;

end

else

begin

ReleaseSemaphore(hSemaphore1,1,nil);

if abs(-T1-125) < 20 then

case WaitForSingleObject(hSemaphore1, 0)of

Wait_Object_0:

begin

f1:=false;

end;

end;

end;

//----- 2й семафор для правого поезда

if (T2>375)and(T2<375+tLength2) then

begin

hSemaphore2 := CreateSemaphore(@sa,1,1,'MySemaphore2');

f2 := false;

if abs(-T1-125) < 20 then f1:= true

else f1:=false;

end

else

begin

ReleaseSemaphore(hSemaphore2,1,nil);

if abs(T1-125) < 20 then

case WaitForSingleObject(hSemaphore2, 0)of

Wait_Object_0:

begin

f2:=false;

end;

end;

end;

Paint;

end;

//--------------- Прорисовка формы ---------------

procedure TForm1.FormPaint(Sender: TObject);

var i : integer;

begin

glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT );

glClearCOlor(0.0,1.0,0.5,0);

glPushMatrix;

glLightfv (GL_LIGHT0, GL_POSITION, @pos);

gluQuadricDrawStyle (quadObj, GLU_FILL);

// Левый поезд

glscalef (0.5,0.5,0.5);

glTranslatef (-3,0,0);

for i := 0 to tVansCount1 -1 do

begin

glpushmatrix;

glcolor3f (1.0,0.0,0.0);

glRotatef (T1,0,1,0);

glRotatef (20*i,0,1,0); //смещение вагонов

glTranslatef (-5,0,0);

MakeVan;

glpopmatrix;

end;

// траектория левого поезда

glPushMatrix;

for i := 1 to 360 do

begin

glColor (1.0, 0.0, 0.0);

glrotate (1, 0, 1, 0);

glBegin (GL_POINTS);

glVertex3f (-5,-0.5,0);

glEnd;

glBegin (GL_POINTS);

glVertex3f (-5.2,-0.5,0);

glEnd;

end;

glPopMatrix;

// траектория правого поезда

gltranslatef (8,0,0);

glPushMatrix;

for i := 1 to 360 do

begin

glColor (0.0, 0.0, 1.0);

glrotate (1, 0, 1, 0);

glBegin (GL_POINTS);

glVertex3f (-5,-0.5,0);

glEnd;

glBegin (GL_POINTS);

glVertex3f (-5.2,-0.5,0);

glEnd;

end;

glPopMatrix;

// правый поезд

for i := 0 to tVansCount2 - 1 do

begin

glpushmatrix;

glcolor3f (0.0,0.0,1.0);

glRotatef (T2,0,1,0);

glRotatef (-20*i,0,1,0);

glTranslatef (-5,0,0);

MakeVan;

glpopmatrix;

end;

glpopmatrix;

SwapBuffers(DC);

end;

//--------------- Формат пиксела ---------------

procedure SetDCPixelFormat (hdc : HDC);

var

pfd : TPixelFormatDescriptor;

nPixelFormat : Integer;

begin

FillChar (pfd, SizeOf (pfd), 0);

pfd.dwFlags := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;

nPixelFormat := ChoosePixelFormat (hdc, @pfd);

SetPixelFormat (hdc, nPixelFormat, @pfd);

end;

//--------------- Создание формы ---------------

procedure TForm1.FormCreate(Sender: TObject);

begin

DC := GetDC (Handle);

SetDCPixelFormat(DC);

hrc := wglCreateContext(DC);

wglMakeCurrent(DC, hrc);

tm1 := 0;

tm2 := 0;

f1 := true;

f2 := true;

// задаём начальные параметры

tVansCount1 := 4;

tVansCount2 := 5;

tLength1 := 20*tVansCount1;

tLength2 := 20*tVansCount2;

tSpeed1 := 10;

tSpeed2 := 10;

glEnable (GL_POLYGON_SMOOTH);

glEnable (GL_LIGHTING);

glEnable (GL_LIGHT0 );

glEnable (GL_DEPTH_TEST);

glEnable (GL_COLOR_MATERIAL);

quadObj := gluNewQuadric;

glShadeModel (GL_SMOOTH);

vnorm := 120;

pos[0]:= -1;

pos[1]:= 0;

pos[2]:= 0;

pos[3]:= 2;

end;

//--------------- Уничтожение формы ---------------

procedure TForm1.FormDestroy(Sender: TObject);

begin

gluDeleteQuadric (quadObj);

wglMakeCurrent(0, 0);

wglDeleteContext(hrc);

ReleaseDC (Handle, DC);

DeleteDC (DC);

end;

//--------------- Изменение размеров формы ---------------

procedure TForm1.FormResize(Sender: TObject);

begin

glViewport(0, 0, ClientWidth, ClientHeight);

glMatrixMode(GL_PROJECTION);

glLoadIdentity;

gluPerspective(vnorm, ClientWidth / ClientHeight, 1.0, 20.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity;

glTranslatef (0.0, 0, -4.0);

glrotatef (90,1,0,0);

InvalidateRect(Handle, nil, False);

end;

//--------------- Выход ---------------

procedure TForm1.bbExitClick(Sender: TObject);

begin

close;

end;

//--------------- Обработка нажатия кнопки мыши ---------------

procedure TForm1.FormClick(Sender: TObject);

begin

Form3.ShowModal;

end;

end.

unit uTrainParams;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls, Spin, Buttons;

type

TForm3 = class(TForm)

GroupBox2: TGroupBox;

Label3: TLabel;

seSpeed1: TSpinEdit;

GroupBox1: TGroupBox;

Label6: TLabel;

seSpeed2: TSpinEdit;

btnGo: TBitBtn;

btnStop: TBitBtn;

btnInfo: TButton;

bbExit: TBitBtn;

GroupBox3: TGroupBox;

procedure btnGoClick(Sender: TObject);

procedure btnStopClick(Sender: TObject);

procedure bbExitClick(Sender: TObject);

procedure seSpeed1Change(Sender: TObject);

procedure seSpeed2Change(Sender: TObject);

procedure btnInfoClick(Sender: TObject);

procedure FormCreate(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form3: TForm3;

f1, f2, f3: boolean;

tSpeed1, tSpeed2: real;

tPriority1, tPriority2: integer;

tVansCount1, tVansCount2, tVansCount3: integer;

tLength1, tLength2, tLength3 : integer;

thread1: THandle; tid:Cardinal;

implementation

{$R *.dfm}

// запуск поезда

procedure TForm3.btnGoClick(Sender: TObject);

var i: integer;

begin

tSpeed1 := seSpeed1.Value;

tSpeed2 := seSpeed2.Value;

GroupBox1.Enabled := false;

GroupBox2.Enabled := false;

f1 := false;

f2 := false;

f3 := false;

btnGo.Enabled:=false;

btnStop.Enabled:=true;

end;

// остановка поезда

procedure TForm3.btnStopClick(Sender: TObject);

begin

tSpeed1 := 0;

tSpeed2 := 0;

f1 := true;

f2 := true;

f3 := true;

btnGo.Enabled := true;

btnStop.Enabled := false;

GroupBox1.Enabled := true;

GroupBox2.Enabled := true;

end;

// закрытие панели управления

procedure TForm3.bbExitClick(Sender: TObject);

begin

CloseHandle (Thread1);

close;

end;

// Скорость первого поезда

procedure TForm3.seSpeed1Change(Sender: TObject);

begin

tSpeed1 := seSpeed1.Value;

end;

// Скорость второго поезда

procedure TForm3.seSpeed2Change(Sender: TObject);

begin

tSpeed2 := seSpeed2.Value;

end;

procedure ThreadProc;

begin

Application.MessageBox('Курсовой проект по ОС на тему "Разработка ПО для регулирования движения поездов при помощи семафора Дейкстра". Выполнила Силина Татьяна, группа ПВ-32', 'Информация об авторе', MB_OK);

end;

// Информация об авторе

procedure TForm3.btnInfoClick(Sender: TObject);

begin

thread1:=CreateThread(nil,0,@ThreadProc,nil,CREATE_SUSPENDED,tId);

ResumeThread (Thread1);

end;

// Создание формы

procedure TForm3.FormCreate(Sender: TObject);

begin

btnStop.Enabled := false;

end;

end.

Соседние файлы в папке docx54