Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
kursovik_ОС 10.doc
Скачиваний:
29
Добавлен:
15.06.2014
Размер:
58.37 Кб
Скачать

Омский государственный технический университет

Кафедра «Автоматизированные системы обработки информации и управления»

Пояснительная записка

к курсовой работе

по теме

Операционные системы

Вариант 10а

Преподаватель

А.Н. Флоренсов

Разработала студент гр. Ас-323

Кузнецова

Виктория Евгеньевна

Омск – 2005 Задание

Разработать под Windows программу, которая в текстовом режиме вывода моделирует следующую задачу.

Между городами А и Б имеется железная дорога, состоящая из перемежающихся участков с двух путным и однопутным движением. Всего таких участков пять. Прилегающие к городам имеют 2 пути. Используя семафоры, описать поведение множества процессов, описывающих движение поездов в обе стороны по этой дороге с учетом ограничения возможностей одного пути (на нем поезда должны двигаться только в одном направлении). Движение каждого поезда должно задаваться отдельной нитью. Всего поездов должно быть 7. Поезд, дошедший до противоположного города, через случайное время отправляется обратно.

1 Алгоритм решения Алгоритм поведения отдельного поезда.

1. Составляем маршрут;

2. Едем до среднего участка;

3. Определяем, можно ли по нему проехать (участок свободен, или направление движения на нем совпадает с направлением движения поезда);

4. Если нельзя, то ждем, пока участок не освободится;

5. Занимаем средний участок, записываем направление движения (для синхронизацией с другими поездами)

6. Проезжаем средний участок;

7. Освобождаем средний участок;

8. Доезжаем до пункта назначения, ждем случайный промежуток времени;

9. Идем на пункт 1.

Алгоритм работы основной нити

1. Инициализация переменных;

2. Создание нитей-поездов;

3. Перерисовка изображения движения в цикле.

Алгоритм перерисовки

1. Нарисовать железную дорогу

2. Нарисовать поезда

Описание глобальных переменных

struct way{

char begin, end;

int speed;

};

Структура описывает текущий маршрут: поезд начинает путь на участке begin и заканчивает на участке end, а едет со скоростью speed.

struct position{

char way, offset;

};

Структура описывает текущее положение поезда на дороге: way задает номер участка, offset - положение на этом участке

way ways[7];

Массив маршрутов. Маршрут каждого поезда хранится по постоянному индексу, равному номеру поезда.

position positions[7];

Массив позиций поездов на железной дороге. Позиция каждого поезда хранится по постоянному индексу, равному номеру поезда.

char nOnMiddle = 0,

Количество поездов, едущих по среднему участку.

char direction = 0;

Направление, в котором поезда едут по среднему участку. Значение 0 означает, что средний участок свободен.

HANDLE hSemaphore

Хэндл для работы с семафором. Семафор служит для синхронизации движения поездов по среднему участку.

HANDLE hstdout;

Хэндл для работы со стандартным выводом.

bool bStop = 0;

Переменная служит для остановки программы.

Листинг программы

#include <windows.h>

#include <process.h>

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

#define GetRandom(min, max) ((rand() % (int)(((max) + 1) - (min))) + (min))

struct way{ //текущий маршрут: из города begin в город end

char begin, end; //со скоростью speed

int speed;

};

struct position{ //текущая позиция поезда на железной дороге

char way, offset; //way - номер участка, offset - положение на этом участке

};

way ways[7]; //7 поездов - 7 маршрутов

position positions[7]; //и 7 позиций на Ж/Д

char nOnMiddle = 0, //количество поездов, едущих по среднему участку

direction = 0; //направление, в котором поезда едут по среднему участку

HANDLE hSemaphore, hstdout;

bool bStop = 0; //переменная служит для остановки программы

/*

Процедура drawWay - прорисовка одного участка железной дороги

Параметры:

х - позиция начала прорисовки по горизонтали

y - позиция начала прорисовки по вертикали

*/

void drawWay(char x, char y)

{

char buffer[17];

COORD coord;

int actLen = 1;

for (int i = 0; i < 17; i++) buffer[i] = 210;

coord.X = x;

coord.Y = y;

WriteConsoleOutputCharacter(hstdout, buffer, 17, coord, (LPDWORD)actLen);

coord.Y = y + 1; coord.X = x;

for (int i = 0; i < 17; i++) buffer[i] = 211;

coord.X = x; coord.Y = y + 1;

WriteConsoleOutputCharacter(hstdout, buffer, 17, coord, (LPDWORD)actLen);

}

/*

Процедура drawTrains - прорисовка железной дороги и всех поездов.

Информация для рисования поездов берется из массива positions.

*/

void drawTrains()

{

char buffer[10];

COORD coord;

int actLen = 1;

//Очищаем место для Ж/Д

coord.X = 3; coord.Y = 5;

WriteConsoleOutputCharacter(hstdout, " ", 60, coord, (LPDWORD)actLen);

coord.Y = 6;

WriteConsoleOutputCharacter(hstdout, " ", 60, coord, (LPDWORD)actLen);

coord.Y = 7;

WriteConsoleOutputCharacter(hstdout, " ", 60, coord, (LPDWORD)actLen);

coord.Y = 9;

WriteConsoleOutputCharacter(hstdout, " ", 60, coord, (LPDWORD)actLen);

drawWay(7, 6);

drawWay(24, 7);

drawWay(7, 8);

drawWay(41, 6);

drawWay(41, 8);

strcpy(buffer, "######"); //квадрат из решеток обозначает город

coord.X = 1;

coord.Y = 10;

WriteConsoleOutputCharacter(hstdout, "Gorod A", 7, coord, (LPDWORD)actLen);

coord.Y = 6;

for (char f = 0; f < 4; f++)

{

WriteConsoleOutputCharacter(hstdout, buffer, 6, coord, (LPDWORD)actLen);

coord.Y++;

}

coord.X = 58;

coord.Y = 10;

WriteConsoleOutputCharacter(hstdout, "Gorod B", 7, coord, (LPDWORD)actLen);

coord.Y = 6;

for (char f = 0; f < 4; f++)

{

WriteConsoleOutputCharacter(hstdout, buffer, 6, coord, (LPDWORD)actLen);

coord.Y++;

}

for (char f = 0; f < 7; f++) buffer[f] = 49 + f;//заполняем массив номерами поездов

for (int j = 0; j < 7; j++)

{

//определяем координаты поезда

if (positions[j].way == 0) {coord.X = 6 + positions[j].offset; coord.Y = 5;}

if (positions[j].way == 1) {coord.X = 6 + positions[j].offset; coord.Y = 7;}

if (positions[j].way == 2) {coord.X = 42 + positions[j].offset; coord.Y = 5;}

if (positions[j].way == 3) {coord.X = 42 + positions[j].offset; coord.Y = 7;}

if (positions[j].way == 4) {coord.X = 24 + positions[j].offset; coord.Y = 6;}

//рисуем его номер...

WriteConsoleOutputCharacter(hstdout, &buffer[j], 1, coord, (LPDWORD)actLen);

coord.Y++;

//и сам поезд

WriteConsoleOutputCharacter(hstdout, "@", 1, coord, (LPDWORD)actLen);

coord.Y++;

WriteConsoleOutputCharacter(hstdout, "@", 1, coord, (LPDWORD)actLen);

}

}

/*

Функция trainThreadProc - описывает поведение поезда на дороге(одна и та же для всех 7 нитей)

В качестве параметра передается номер поезда (начиная с нуля)

*/

unsigned __stdcall trainThreadProc(void *arg)

{

char source = ways[(int)arg].begin; //source - пункт отправления

char dest, //dest - пункт назначения

i,

curDir, //направление движения

offset; //единичное смещение (зависит от направления)

while (bStop == 0)

{

Sleep(GetRandom(200, 3000)); //случайная задержка перед отправлением

if (source < 2) dest = GetRandom (2, 3);

else dest = GetRandom (0, 1);

curDir = (dest > source)? 1 : 2; //определяем направление

ways[(int)arg].begin = source; //записываем маршрут в массив,

ways[(int)arg].end = dest; //для синхронизации движения

//задаем позицию поезда для прорисовки

positions[(int)arg].way = source;

if (curDir == 1){

positions[(int)arg].offset = 0;

offset = 2;

}

else{

positions[(int)arg].offset = 17;

offset = -2;

}

for (i = 0; i < 9; i++)

{

Sleep(ways[(int)arg].speed);

positions[(int)arg].offset += offset;

}

//подъезжаем к среднему участку и ждем, пока он освободится или

//если по нему в том же направлении уже едут поезда, то едем за ними

for (i = 0; i < 1; i++)

if ((direction != 0)&&(curDir != direction))

{

Sleep(500);

i = -1;

};

//если участок был свободен, указываем свое направление движения

if (direction == 0)

direction = curDir;

WaitForSingleObject(hSemaphore, INFINITE);

nOnMiddle++;

positions[(int)arg].way = 4;

if (curDir == 1){

positions[(int)arg].offset = 0;

offset = 2;

}

else{

positions[(int)arg].offset = 17;

offset = -2;

}

for (i = 0; i < 8; i++)

{

Sleep(ways[(int)arg].speed);

positions[(int)arg].offset += offset;

}

ReleaseSemaphore(hSemaphore, 1, NULL);

nOnMiddle--;

//если участок освободился, сбрасываем направление

if (nOnMiddle == 0) direction = 0;

positions[(int)arg].way = dest;

if (curDir == 1){

positions[(int)arg].offset = 0;

offset = 2;

}

else{

positions[(int)arg].offset = 17;

offset = -2;

}

for (i = 0; i < 9; i++)

{

Sleep(ways[(int)arg].speed);

positions[(int)arg].offset += offset;

}

source = dest; //указываем, в каком городе поезд стоит теперь

}

_endthreadex(0);

return 0;

}

int main(int argc, char* argv[])

{

HANDLE hthread1, hthread2, hthread3, hthread4, hthread5, hthread6, hthread7;

unsigned int threadid1, threadid2, threadid3, threadid4, threadid5, threadid6, threadid7;

hstdout=GetStdHandle(STD_OUTPUT_HANDLE); //получаем хэндл стандартного вывода

hSemaphore = CreateSemaphore(NULL, 7, 0, NULL); //создаем семафор с макс. значением 7

//случайным обазом расставляем поезда и назначаем им скорости

//(чем меньше число, тем больше скорость)

for (int i = 0; i < 7; i++) {

ways[i].begin = GetRandom(0, 3);

ways[i].speed = GetRandom(200, 700);

}

//создаем 7 нитей

hthread1 = (HANDLE)_beginthreadex(NULL, 4096, &trainThreadProc, (void *)0, 0, &threadid1);

hthread2 = (HANDLE)_beginthreadex(NULL, 4096, &trainThreadProc, (void *)1, 0, &threadid2);

hthread3 = (HANDLE)_beginthreadex(NULL, 4096, &trainThreadProc, (void *)2, 0, &threadid3);

hthread4 = (HANDLE)_beginthreadex(NULL, 4096, &trainThreadProc, (void *)3, 0, &threadid4);

hthread5 = (HANDLE)_beginthreadex(NULL, 4096, &trainThreadProc, (void *)4, 0, &threadid5);

hthread6 = (HANDLE)_beginthreadex(NULL, 4096, &trainThreadProc, (void *)5, 0, &threadid6);

hthread7 = (HANDLE)_beginthreadex(NULL, 4096, &trainThreadProc, (void *)6, 0, &threadid7);

while (true){

drawTrains();

Sleep(100);

}

return 0;

}

Соседние файлы в предмете Операционные системы