
Добавил:
Yanus
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:trains
.cpp#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;
}
Соседние файлы в предмете Операционные системы