• B правой части каждого сообщения есть стрелки и . Не стесняйтесь оценивать ответы. Чтобы автору вопроса закрыть свой тикет, надо выбрать лучший ответ. Просто нажмите значок в правой части сообщения.

Задача: Алгоритмы планирования(диспетчеризации)

  • Автор темы ge4r
  • Дата начала
G

ge4r

Добрый день,нужно накатать 2 таких алгоритма и вычислить параметры их работы сравнить их.
параметры - это различные величины,получаемые из общего времени нахождения процесса в системе(в коде gtime) и времени его непрерывной работы(в коде cburst);

вот FCFS попытался накатать,но он не хочет работать,видимо ошибка в методе fcfs




C++:
#include <iostream>
#include <stdlib.h>

using namespace std;
int n;
class process {
public:
int stime;
int burst;
int cburst;
int gtime;
int priority;
int completed;
int number;
float M;
float R;
float P;

process() {
this->burst=0;
this->stime=0;
this->priority=0;
}

~process() {};
};

void random (process procs[]){
for (int i=0;i<n;i++) {
procs[i].stime=rand() % 10;
procs[i].burst=rand() % 100 + 1;
procs[i].cburst=procs[i].burst;
procs[i].completed=0;
procs[i].number=i;
procs[i].priority=rand()%4 +1;
}
}

process* min_stime(process procs[]){
int min_time = INT_MAX;
process *min;
for (int i=0;i<n;i++){
if(procs[i].completed==0 && procs[i].stime<min_time){
min_time=procs[i].stime;
min=&procs[i];
}
}
return min;
}

void fcfs (process procs[]){
process *cur=min_stime(procs);
int tick=0;
while(cur!=NULL) {
if (cur->burst==0){
cur->completed=1;
}
if (cur->completed==1){
cur->gtime=tick-cur->stime;
cur=min_stime(procs);
if (cur==NULL) break;
}
if (tick>= cur->stime){
cur->burst--;
}
tick++;
}
}

void count (process procs[]){
for (int i=0;i<n;i++){
procs[i].M=procs[i].gtime-procs[i].cburst;
procs[i].R=procs[i].cburst/procs[i].gtime;
procs[i].P=1/procs[i].R;
}
}






int main(int argc, char *argv[])
{
cout<<"Input n: ";
cin>>n;
process procs[n];
random(procs);
fcfs(procs);
count (procs);
for (int i=0;i<n;i++){
printf("M= ",procs[i].M);
}



system("PAUSE");	 
return 0;
}
 
G

ge4r

нужен еще srr. спасибо,сейчас буду разбирать код)

по srr сейчас опишу,как понял алгоритм.

делаем еще поле chosen булевое. если =1 то процесс выбранный ,если =0 то новый. рандомизируем его. задаем всем процессам рандомный или введеный с консоли приоритет. берем 2 коэффицента dA dB, такие что dB>dA , прибавляем их в зависимости от вида процесса. далее работаем с выбранными,ибо приоритет их больше будет. берем из выбранных с минимальным временем входа,обрабатываем ,переходим к следующему и так все выбранные. потом переходим к новым и тоже самое делаем с ними. вроде так?

Апдейт. код понятен, вот только никогда не сталкивался с такой записью void method(void) это аналогично просто пустому списку параметров?

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

someone

Спасибо, вы очень помогли!) кстати а что с srr не понятно? он считывает данные с файла..
 
D

DarkKnight

Вот вам оба в одном проекте, анализируйте на здоровье.....

C++:
/*
codeby.net
Autor: DarkKnight125 (Denis Goncharov)
*/
#include <iostream>
#include <time.h>

using namespace std;

using namespace std;

//Класс процесс
class process {
public:
int stime; //Время вхождение процесса в систему
int burst; // А это как я понимаю, за сколько процессортных циклов выполниться процесс (итераций-тактов до завершения)
int cburst; // Время в работе
int gtime; //Общее время нахождения процесса в системе 
int priority; //Приоритет
bool completed; //Флаг выполнения (сделаем bool)
int number; //Наверное номер процесса, *пока не знаю точно*
float M;
float R;
float P; 
//Конструктор по умолчанию
process() 
{
//Обнулим все
stime = 0;
burst=0;
cburst = 0;
gtime=0;
priority=0;
completed= false;
M=0;
R=0;
P=0;
}
~process() {};

void random(int Number)
{
stime= rand() % 100 +1;
burst= rand() % 50 + 1;
cburst=0;
completed=0;
number= Number;
priority=rand()%4 +1;
}

//Подсчет статистических данных *после завершения процесса*
void InitStatictic(void)
{
M = gtime - cburst; //Потери времени
R = (double) cburst/gtime; //Реактив.
P = (double) gtime/cburst; //Штраф
}
//Статистика процесса (для завершенных процессов)
void ShowStatProcess(void)
{
cout << "Процесс(ID:"<< number << ") gtime = " << gtime << "; cburst = "<< cburst<<" Коэф. M=" << M << ";R="<< R <<";P=" <<P << endl;
cout << "Процесс создан в " << stime <<" квант/такт от нач. исполнения программы"<< endl << endl;
}
};

//Структура очереди
struct PrcQ 
{
process data; //Информация по процессу
PrcQ *Next; //Указатель на след. процесс очереди
};

//Конечно проще и адекватнее использовать двунаправленный список, но все же у нас процессы, и поэтому мы ограничимся обычной очередью,
//Пусть и алгоритм удаления из середины и конца будет немного громозким, зато для отценки любого из алгоритмов методички, этот подход самый наилучший
//Класс очередь процессов
class QProcess
{
public:
PrcQ	Elt; //Элемент очереди	
PrcQ	*First; //Указатель на первый элемент очереди
PrcQ	*Curr; //Текущий (хвост очереди) элемент очереди

//Конструктор класса очереди поумолчанию
QProcess()
{
First = NULL; //Выставим указатели начала и хвоста в нуль (пустая очередь)
Curr = NULL;
}
//Функция добавления элемента в очередь
void ArrProcess(process pr)
{
PrcQ *Temp = new PrcQ; //Выделим память под элемент очереди
Temp ->data = pr; //Запишим в нее инфу по процессу
Temp ->Next = NULL; //Указатель на след. элемент выставим в NULL (т.к. добавляем только в конец очереди)

if (!First) //Если указатель на начало NULL, то очередь пустая
{
First = Curr = Temp; //Присвоим ук. на начало, хвосту, текущий доб. элемент
}
else //Если же очередь не пуста
{
Curr->Next = Temp; //Указатель на след. элемент выставим в наш новый элемент
Curr = Temp; //Присвоим хвосту адрес нов. элемента
}
}

//Функция исключения (переноса) процесса в другую очередь)
//Входные данные Number - номер (ID) процесса
//				 toQProcess - ссылка на очередь к которую процесс переместить
// Результат true - если процесс найден и перемещен, false - если процесса с такии ID нет
bool InvateTo(int Number, QProcess &toQProcess)
{
PrcQ *Temp = First; //Заведем временную переменую в которую поставим начало очереди - которая вызывает функцию (из которой процесс изымается)
PrcQ *LastTemp = NULL; //Указатель на предыдущий элемент
PrcQ *MustDel = NULL; //Элемент очереди который будет удален (т.к. мы выделяем память в функции AddProcess)
bool Search = false; // Поставим флаг поиска в false

//Если удаляемый первый элемент если id процесса = Number
if (Temp->data.number == Number) //Если первый в очереди процесс равен Number
{
MustDel = Temp; //Выставим указатель удаления на память этого элемента
First = Temp->Next; //Первому элементу очереди присвоим процесс следующего
Search = true; //Флаг поиска установим в true
}
else //Инача (т.е. удаляемый (переносимый) процесс не первый, то
{
while (Temp->Next) //Циклим до тех пор, пока укатель Temp->Next не укажет на NULL (иными словами до последнего элемента, не включая его)
{
//Если в цикле был найден элемент с нужным номером (Id)
if (Temp->Next->data.number == Number)
{
//То инициализируем его удаление
MustDel = Temp->Next; 
Temp->Next = Temp->Next->Next;
Search = true;
break;
}
LastTemp = Temp; //Сюда пишим текущий (после итерации он предыдущий)элемент (он нам понадобиться для проверки, если процесс переноса - последний)
Temp = Temp->Next; //Перейдем к след. элементу
}
//Проверим не является ли удал. процесс последним
if (Temp->data.number == Number)
{
MustDel =Temp;
Curr = LastTemp;
Curr->Next = NULL;
}
}	

//Если есть что удалять (перемещать)
if (MustDel)
{
toQProcess.ArrProcess(MustDel->data); //Добавим в очередь(в которую переправляем) процесс
delete MustDel; //Почистим память выделеную для процесса
}
return Search; //Вернем результат
}
};

//Алгоритм fcfs
//Входные данные Work - очередь процессов уже запущенных
//				 Complete - очередь процессов уже завершенных
//				 Feature - очередь процессов которые еще не запустились
void fcfs (QProcess &Work, QProcess &Complete, QProcess &Feature)
{
//Итак начнем... Алгоритм fcfc
unsigned int Tick = 0; //Кванты процессорного времени (так называемы тики) //Для начала обнулим
PrcQ *Temp;
//Пока есть хоть один процесс в работе или в будущих процессах то выводняем
while (Work.First || Feature.First)
{
//Если время наступило, то перенесем процессы их Feature в Work
PrcQ *TempFeature = Feature.First; //Установим указатель на Feature.First
while (TempFeature) //Пока указатель не NULL выполняем поиск процессов которые должны запустить на этом такте (обходим очередб)
{
//Если время запуска процесса соответствует такту
if (TempFeature->data.stime == Tick)
{
Temp = TempFeature->Next; //То запомним указатель на след. элемент
Feature.InvateTo(TempFeature->data.number,Work); //Перенесем из Feature в Рабочую (Work) очередь
TempFeature = Temp; //Перейдем к след. элементу в очереди
}
else
TempFeature = TempFeature->Next; //Если ничего не найдено, то просто перейдем к след. элементу очереди
}

//Ну вот, с процессами которые должны войти все.. Перейдем теперь к рабочим
//По алгоритму FCFS (Первый вошел - он и выполняете) мы не отпустим процесс пока не завершим его
PrcQ *TempWork = Work.First; //Поэтому Получим первый процесс в очереди Work
//И будем выполнять его на этом такте если конечно процесс в рабочей очереди вообще есть
if (TempWork)
{
TempWork->data.burst--; //Уменьшим такты до завершения
TempWork->data.cburst++; //Увеличим время работы процесса
}

//На этом такте с процессом все.. Теперь в рабочих процесса увеличим время их нахождения в системе и если он завершился то перенесем его в
//очередь завершенных
TempWork = Work.First; //Поставим указатель на первый элемент очереди (рабочей)
while (TempWork)
{
TempWork->data.gtime++; //Увеличим время нахождения процесса в системе
if(TempWork->data.burst == 0) //Процесс завершился
{
TempWork->data.InitStatictic(); //Расчет статистики по процессу
Temp = TempWork->Next;
Work.InvateTo(TempWork->data.number,Complete);
TempWork = Temp;
}
else
TempWork = TempWork->Next;
}

Tick++; //Увеличим квант
}
}

//Алгоритм SRR (selfish RR – эгоистичный RR)
//Входные данные Work - очередь процессов уже запущенных
//				 Complete - очередь процессов уже завершенных
//				 Feature - очередь процессов которые еще не запустились
void srr (QProcess &Work, QProcess &Complete, QProcess &Feature)
{
const int dA = 3; //Приращение для новых процессов
const int dB = 1; //Приращение для выбранных процессор
//Итак начнем... Алгоритм SRR
unsigned int Tick = 0; //Кванты процессорного времени (так называемы тики) //Для начала обнулим
PrcQ *Temp;
//Пока есть хоть один процесс в работе или в будущих процессах то выполняем
while (Work.First || Feature.First)
{
//Если время наступило, то перенесем процессы их Feature в Work
PrcQ *TempFeature = Feature.First; //Установим указатель на Feature.First
while (TempFeature) //Пока указатель не NULL выполняем поиск процессов которые должны запустить на этом такте (обходим очередь)
{
//Если время запуска процесса соответствует такту
if (TempFeature->data.stime == Tick)
{
Temp = TempFeature->Next; //То запомним указатель на след. элемент
Feature.InvateTo(TempFeature->data.number,Work); //Перенесем из Feature в Рабочую (Work) очередь
TempFeature = Temp; //Перейдем к след. элементу в очереди
}
else
TempFeature = TempFeature->Next; //Если ничего не найдено, то просто перейдем к след. элементу очереди
}

//Теперь сама суть SRR, Нам нужно выстроить рабочую очередь по убыванию приоритетов
QProcess WorkNew; // Новая очередь
PrcQ *TempWork = Work.First; //Поэтому Получим первый процесс в очереди Work
while (TempWork) //Теперь будем обходить рабочую очередь пока в ней не останется ни одного элемента (все они должны перейти в нов. раб. очередь)
{
PrcQ *TempWork2 = Work.First; //Еще один указатель на первый эл. Work (для влож. цикла), мы же ищим макс. приоритеты
PrcQ *Replace = NULL; //Какой эл. очереди будем вытеснять
int MaxPrioritet = -1; //Максимальное значение приоритета (выставим его в минимум = -1)
while(TempWork2) //Пока не обошли всю очередь
{
if (TempWork2->data.priority > MaxPrioritet) //Если приоритет процесса > MaxPrioritet, то
{
Replace = TempWork2; //Запомним указатель на элемент
MaxPrioritet = TempWork2->data.priority; //Перезапишим макс. значение приоритета
}
TempWork2 = TempWork2->Next; //Перейдем к след. элементу
}
Work.InvateTo(Replace->data.number,WorkNew);//Запишим в новую очередь WorkNew процесс с макс приоритетом
TempWork = Work.First; //Поэтому Получим первый процесс в очереди Work и продолжным искать макс. приоритет из оставщихся элементов
}
Work = WorkNew; //Заменим очереди

//По алгоритму SRR выполним первый процесс на 1 такт и перещитаем приоритеты
TempWork = Work.First; //Поэтому Получим первый процесс в очереди Work
if (TempWork)
{
TempWork->data.burst--; //Уменьшим такты до завершения
TempWork->data.cburst++; //Увеличим время работы процесса
}

//На этом такте с процессом все.. Теперь в рабочих процесса увеличим время их нахождения в системе и если он завершился то перенесем его в
//очередь завершенных
TempWork = Work.First; //Поставим указатель на первый элемент очереди (рабочей)
while (TempWork)
{
TempWork->data.gtime++; //Увеличим время нахождения процесса в системе

//Вот тут будем пересчитывать приоритеты
if (TempWork->data.cburst == 0) //Если управление вообще не было еще переданно процессу
TempWork->data.priority += dA; //То увеличим на dA = 3
else TempWork->data.priority += dB; //Иначе (процесс уже хоть раз но выполнялся) на dB = 1;

if(TempWork->data.burst == 0) //Процесс завершился
{
TempWork->data.InitStatictic(); //Расчет статистики по процессу
Temp = TempWork->Next;
Work.InvateTo(TempWork->data.number,Complete);
TempWork = Temp;
}
else
TempWork = TempWork->Next;
}

Tick++; //Увеличим квант
}
}

//Вот, на этом этапе весь интерфес для задания полностью разработан, остается только описать алгоритмы диспечерезации процессов

//Главная форм программы (точка входа)
int main(int argc, char *argv[])

{	  
setlocale(LC_ALL,".1251"); //Подгрузка локали
srand(time(NULL)); //Инициализация генератора случ. величины

int n=0; //Кол-во процессов
cout<<"Введите кол-во процессов n = ";
cin>>n; //Ввод кол-ва

//Теперь перейдем к очередям
QProcess Work; //Очередь которая обрабатывает (процесс уже запущен) FCFS
QProcess NewProcess; //Очередь процессов время запуска которых еще не наступило FCFS
QProcess Complete; //Очередь которая уже обработалась (конец - последний обработанный) FCFS
// и тоже для SRR
QProcess WorkSRR; //Очередь которая обрабатывает (процесс уже запущен) SRR
QProcess NewProcessSRR; //Очередь процессов время запуска которых еще не наступило SRR
QProcess CompleteSRR; //Очередь которая уже обработалась (конец - последний обработанный) SRR

process InitRand; 

// Рандомная инициализация процессов 
for (int i = 0; i<n; i++)
{
InitRand.random(i+1); //Сама инициализация процесса рандомным методом
NewProcess.ArrProcess(InitRand); //Добавление в очередь (процессов время запуска которых еще не наступило) FCFS
InitRand.priority = 1; //изменим приоритет для SRR (там первоначально все приоритеты равны)
NewProcessSRR.ArrProcess(InitRand); //Добавление в очередь (процессов время запуска которых еще не наступило) SRR
}

PrcQ *Temp; //Указатель на структуру очереди

//Вывод очереди завершенных процессов FCFS
fcfs(Work,Complete,NewProcess);
cout << "Очередь Завершенных процессов FCFS:" << endl;
Temp = Complete.First;
while(Temp)
{
Temp->data.ShowStatProcess();
Temp = Temp->Next;
}

cout << "----------------------------------------------------" << endl;
//Вывод очереди завершенных процессов SRR
srr(WorkSRR,CompleteSRR,NewProcessSRR);
cout << "Очередь Завершенных процессов SRR:" << endl;
Temp = CompleteSRR.First;
while(Temp)
{
Temp->data.ShowStatProcess();
Temp = Temp->Next;
}


system("PAUSE");	
return 0;
}
 

Вложения

  • srr.jpg
    srr.jpg
    126,6 КБ · Просмотры: 500
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!