Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Омский государственный технический университет
Кафедра «Автоматизированные системы обработки информации и управления»
Пояснительная записка
к курсовой работе
по теме
Операционные системы
Вариант 10а
Преподаватель |
|
А.Н. Флоренсов |
|
Разработала студент гр. Ас-323 Кузнецова |
|
Виктория Евгеньевна |
|
Омск 2005
Разработать под Windows программу, которая в текстовом режиме вывода моделирует следующую задачу.
Между городами А и Б имеется железная дорога, состоящая из перемежающихся участков с двух путным и однопутным движением. Всего таких участков пять. Прилегающие к городам имеют 2 пути. Используя семафоры, описать поведение множества процессов, описывающих движение поездов в обе стороны по этой дороге с учетом ограничения возможностей одного пути (на нем поезда должны двигаться только в одном направлении). Движение каждого поезда должно задаваться отдельной нитью. Всего поездов должно быть 7. Поезд, дошедший до противоположного города, через случайное время отправляется обратно.
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;
}
1. January 2004 Release of the MSDN Library