Вариант задания 18
Вариант |
Кол-во процессов |
Кол-во ресурсов |
18 |
4 |
2 |
Код программы
//---------------------------------------------------------------------------
#include <vcl.h>
#include <conio.h>
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma argsused
#include <math.h>
#include <cstdio>
#define NUM_PROC 4 // количество процессов
#define NUM_RES 2 // количество ресурсов
struct Resource // Структура данных ресурса (п. 2, 3)
{
int id, s; // идентификатор и семафор
int waiters[NUM_PROC]; // список ожидающих ресурс процессов (п. 4)
int owner; // текущий владелец ресурса
};
//===================================================
// Код получения ресурса:
bool P(int& s)
{
// Функция уменьшения значения семафора (п. 1)
// Возвращает true, если значение семафора уменьшено,
// и false, если уменьшение невозможно.
if (s > 0)
{
s -= 1;
return true;
}
else return false;
}
//===================================================
void insert(int* arr, int val)
{
// Процедура добавления процесса в конец очереди (п. 5)
int i = 0;
while (arr[i] != -1) i++;
arr[i] = val;
arr[i+1] = -1; // в конце очереди всегда стоит -1
}
//===================================================
void wait(Resource& res, int proc)
{
// Процедура постановки в очередь на ресурс res процесса с номером proc (п. 1)
insert(res.waiters, proc);
}
//===================================================
bool seize(Resource& res, int proc)
{
// Процедура получения доступа к ресурсу res процессом с номером proc.
// Возвращает true, если доступ получен, и false, если процесс поставлен в очередь.
if (P(res.s)) // Шаг 1 алгоритма А1
{ // Шаг 2 алгоритма А1:
res.owner = proc;
return true;
}
else
{ // Шаг 3 алгоритма А1:
wait(res, proc);
return false;
}
}
//===================================================
// Код освобождения ресурса:
void V(int& s)
{
// Функция увеличения значения семафора (п. 1)
if (s == 0) s += 1;
}
//===================================================
int allocator(Resource& res)
{
// Функция, возвращающая номер процесса, который получит доступ к ресурсу следующим (п. 7)
return res.waiters[0]; // в простейшем случае, возвращает следующий процесс в очереди
}
//===================================================
void remove(int* arr, int val)
{
// Процедура удаления процесса из очереди (п. 6)
int i = 0;
while (arr[i] != val) i++;
do
{
arr[i] = arr[i+1];
i++;
}
while (arr[i] != -1);
}
//===================================================
void signal(Resource& res)
{
// Процедура оповещения о том, что ресурс res свободен (п. 1)
// Возвращает false, если ресурс теперь занят другим процессом,
// и true, если ресурс свободен.
int next = allocator(res);
remove(res.waiters, next);
res.owner = next;
}
//===================================================
void release(Resource& res)
{
// Процедура освобождения ресурса res.
if (res.waiters[0] == -1) // Шаг 1 алгоритма А2
{ // Шаг 2 алгоритма А2:
V(res.s);
res.owner = -1;
}
else
{ // Шаг 3 алгоритма А2:
signal(res);
}
}
//===================================================
// Код, реализующий пользовательский интерфейс:
int main()
{//1
Resource resource[NUM_RES]; // массив ресурсов
for (int i = 0; i < NUM_RES; i++)
{//2
resource[i].id = i;
resource[i].s = 1;
resource[i].waiters[0] = -1; // очередь пуста
resource[i].owner = -1; // ресурс свободен
}//2
int blocked[NUM_PROC]; // массив определяет, какой ресурс сейчас ожидает процесс
for (int i = 0; i < NUM_PROC; i++)
{
blocked[i] = -1; // означает, что процесс не ожидает никакого ресурса
}
setlocale(LC_ALL, "rus");
printf("В вашем распоряжении имеется %d процессов и %d ресурса.\n", NUM_PROC, NUM_RES);
printf("Чтобы выйти, в любой момент введите 0.\n");
while (true)
{//3
printf("\n");
int proc, res;
do
{//4
printf("Введите номер процесса (от 1 до %d): ", NUM_PROC);
scanf("%d", &proc);
}//4
while (proc < 0 || proc > NUM_PROC);
if (proc == 0)
{//5
printf("Программа динамического моделирования завершила работу.");
getch();
return 0;
}//5
else
{
proc -= 1; // делаем номер процесса индексом массива
}
if (blocked[proc] != -1)
{//6
printf("Процесс заблокирован в ожидании ресурса %d.\n", blocked[proc]+1);
continue;
}//6
do
{//7
printf("Введите номер ресурса (от 1 до %d): ", NUM_RES);
scanf("%d", &res);
}//7
while (res < 0 || res > NUM_RES);
if (res == 0)
{//8
printf("Программа динамического моделирования завершила работу.");
getch();
return 0;
}//8
else
{
res -= 1; // делаем номер ресурса индексом массива
}
if (resource[res].owner != proc)
{//9
if (seize(resource[res], proc))
{
printf("Ресурс #%d успешно занят процессом #%d.\n", res+1, proc+1);
}
else
{//10
blocked[proc] = res;
printf("Процесс #%d заблокирован в ожидании ресурса #%d.\n", proc+1, res+1);
}//10
}//9
else
{//11
release(resource[res]);
printf("Процесс #%d освободил ресурс #%d.\n", proc+1, res+1);
if (resource[res].owner != -1)
{//12
blocked[resource[res].owner] = -1;
printf("Процесс #%d разблокирован и теперь занимает ресурс #%d.\n", resource[res].owner+1, res+1);
}//12
}//11
}//3
}//1
