Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование для ЭВМ, Л.р.1-4.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
410.87 Кб
Скачать
  1. Содержание отчёта

  1. Наименование работы

  2. Цель работы

  3. Краткие теоретические сведения

  4. Вариант задания

  5. Код программы

  6. Пример работы программы

  7. Анализ полученных результатов и выводы

  8. Подпись исполнителя

Приложение 1 Пример работы программы

В вашем распоряжении имеется 8 процессов и 3 ресурса.

Чтобы выйти, в любой момент введите 0.

Введите номер процесса (от 1 до 8): 1

Введите номер ресурса (от 1 до 3): 1

Ресурс #1 успешно занят процессом #1.

Введите номер процесса (от 1 до 8): 5

Введите номер ресурса (от 1 до 3): 1

Процесс #5 заблокирован в ожидании ресурса #1.

Введите номер процесса (от 1 до 8): 6

Введите номер ресурса (от 1 до 3): 1

Процесс #6 заблокирован в ожидании ресурса #1.

Введите номер процесса (от 1 до 8): 5

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

Введите номер процесса (от 1 до 8): 1

Введите номер ресурса (от 1 до 3): 1

Процесс #1 освободил ресурс #1.

Процесс #5 разблокирован и теперь занимает ресурс #1.

Введите номер процесса (от 1 до 8): 0

Программа динамического моделирования завершила работу.

Приложение 2. Код программы

#include <locale.h>

#include <math.h>

#include <cstdio>

#define NUM_PROC 8 // количество процессов

#define NUM_RES 3 // количество ресурсов

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()

{

Resource resource[NUM_RES]; // массив ресурсов

for (int i = 0; i < NUM_RES; i++)

{

resource[i].id = i;

resource[i].s = 1;

resource[i].waiters[0] = -1; // очередь пуста

resource[i].owner = -1; // ресурс свободен

}

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)

{

printf("\n");

int proc, res;

do

{

printf("Введите номер процесса (от 1 до %d): ", NUM_PROC);

scanf("%d", &proc);

} while (proc < 0 || proc > NUM_PROC);

if (proc == 0)

{

printf("Программа динамического моделирования завершила работу.");

return 0;

}

else

proc -= 1; // делаем номер процесса индексом массива

if (blocked[proc] != -1)

{

printf("Процесс заблокирован в ожидании ресурса %d.\n", blocked[proc]+1);

continue;

}

do

{

printf("Введите номер ресурса (от 1 до %d): ", NUM_RES);

scanf("%d", &res);

} while (res < 0 || res > NUM_RES);

if (res == 0)

{

printf("Программа динамического моделирования завершила работу.");

return 0;

}

else

res -= 1; // делаем номер ресурса индексом массива

if (resource[res].owner != proc)

if (seize(resource[res], proc))

printf("Ресурс #%d успешно занят процессом #%d.\n", res+1, proc+1);

else

{

blocked[proc] = res;

printf("Процесс #%d заблокирован в ожидании ресурса #%d.\n", proc+1, res+1);

}

else

{

release(resource[res]);

printf("Процесс #%d освободил ресурс #%d.\n", proc+1, res+1);

if (resource[res].owner != -1)

{

blocked[resource[res].owner] = -1;

printf("Процесс #%d разблокирован и теперь занимает ресурс #%d.\n", resource[res].owner+1, res+1);

}

}

}

}