Курсовой проект (774312), страница 2
Текст из файла (страница 2)
Статистика будет состоять из трёх частей:заголовочной, пошаговой и итоговой.Заголовочная часть содержит: список процессов и их приоритетов, а также заголовки свободного количества устройств(состояние семафора на конец текущего шага) и временивыполнения.–8–Внешний вид заголовочной части:processes: Apriority: highBnormClow... sem.time/i...processes — процессы, priority — приоритет, high — высокий(1), norm — средний (2), low — низкий (3), sem.
— текущеезначение семафора, time/i (idle) — время работы и времяпростоя на текущем шаге и за всё время.Пошаговая часть содержит информацию о текущем шагеработы менеджера процессов. Внешний вид:step12:1>0run2>11>0sleep d:run......-3- + 2/0= 15/1step 12 — номер текущего шага, 1>0 — состояние переменнойдля соблюдения приоритета процесса до и после выполнениятекущего шага, -3- — значение семафора, + 2/0 — время работыи простоя на текущем шаге, = 15/1 — время работы/простоя завсё время моделирования, run — состояние процесса.Возможные состояния процесса: sleep — процесс пропущенна текущем шаге, run — процесс отработал на текущем шагеодну единицу времени, wait — процесс ждёт освобожденияустройства, d:run — процесс занял устройство и отработал с нимодну единицу времени, d:slp — процесс занял устройство и ждётрезультатов его работы, end — процесс завершил свою работу.Итоговая часть содержит время выполнения каждогопроцесса в отдельности и всех вместе.
Внешний вид:-------------------------------------------TotalTime: 132637...= 37–9–Граф взаимодействия объектов программыОписание классов:● Manager — класс эмулирующий работу менеджера процессов;● Process — класс эмулирующий работу процесса;● ProcessOptions — шаблон работы процесса;● PredeviceEmulator — эмулятор работы процесса до работыс устройством;● IndeviceEmulator — эмулятор работы процесса с устройством;● PostdeviceEmulator — эмулятор работы процесса после работыс устройством;● Devices — менеджер устройств, семафор.– 10 –Исходный код программыИсходный код файла «Data.h»:#pragma once#define TotalDeviceCount 3// Доступные типы эмуляторов работы процессаenum EmulatorType { EmulatorType_Predevice, EmulatorType_Indevice,EmulatorType_Postdevice };// Доступные варианты результата работы процесса в течении выделенного// интервала времени.enum Result { Result_Sleep, Result_Run, Result_Wait, Result_Finish };// Абстрактный класс эмулятора работы процессаclass BaseEmulator;// Класс задаёт шаблон работы одного процессаclass ProcessOptions {public:ProcessOptions(int PredeviceTicks, int IndeviceTicks, int WaitDeviceTicks,int DeviceCount, int PostdeviceTicks, int TotalCount, int Priority);int PredeviceTicks; // Время выполнения до захвата устройстваint IndeviceTicks;// Время выполнения работы с устройствомint WaitDeviceTicks; // Время ожидания формирования результата устройствомint DeviceCount;// Кол-во повторений работы с устройствомint PostdeviceTicks; // Время выполнения после захвата устройстваint TotalCount;// Кол-во полных повторений работы процессаint Priority;// Приоритет процесса};// Класс эмулирует работу одного процесса по заданному шаблонуclass Process {public:Process(ProcessOptions* Options); // Конструктор классаprotected:ProcessOptions* m_Options;int m_CurrentPriority;int InstateTicks;int TotalStep;BaseEmulator* m_Emulator;int m_FinishTick;bool m_NoPrint;Result m_LastResult;////////////////public:Result DoTick(int TotalTick);void PrintState();void PrintPriority();static void PrintSemafore();int GetFinishTick();int GetPriority();Result GetResult();};Шаблон работы процессораТекущий приоритетОтработано тактов в текущем состоянииТекущий шаг общийТекущий эмулятор работы процессаВремя, на котором работа была оконченаБлокировка вывода статистикиПоследний результат работы процесса//////////////Отработать текущий шагВывести состояние в последнем вызовеВывести приоритет в последнем вызовеВывести кол-во свободных устройствВремя, на котором работа была оконченаПриоритет процесса по шаблонуПоследний результат работы процесса– 11 –Исходный код файла «Data.cpp»:#include "stdafx.h"#include "Data.h"// Класс эмулирующий работу семафораclass Devices {public:// Конструктор классаDevices(int DeviceCount) {this->CurrentCount = DeviceCount;}// Текущее кол-во свободных устройствint CurrentCount;// Попытаться занять устройствоbool GetDevice() {if (this->CurrentCount) {this->CurrentCount--;return true;} elsereturn false;}};// Освободить устройствоvoid ReleaseDevice(){ this->CurrentCount++; }// Устройства, эмулятор семафораDevices* g_Devices = new Devices(TotalDeviceCount);// Базовый абстрактный класс эмулятора работыclass BaseEmulator abstract {public:Result virtual DoTick(int TotalTick) = 0;bool virtual IsFinished() = 0;EmulatorType virtual GetType() = 0;void virtual PrintState() = 0;};процесса////////Отработать текущий шагЭмулятор закончил работу?Тип класса эмулятораВывод текущего состояния// Базовый класс эмулятор работы процесса до и после работы с устройствомclass BaseNodeviceEmulator abstract : public BaseEmulator{protected:int m_TicksToWork; // Время, которое осталось обрабатывать устройствоpublic:// Отработать текущий шагResult DoTick(int TotalTick) {m_TicksToWork--;return Result_Run;}// Эмулятор закончил эмуляцию своей части шаблона работы процесса?bool IsFinished() { return !m_TicksToWork; }// Вывод текущего состояния работы процессаvoid PrintState() { printf(" run "); }};– 12 –// Эмулятор работы процесса до работы с устройствомclass PredeviceEmulator : public BaseNodeviceEmulator {public:// Конструктор классаPredeviceEmulator(ProcessOptions* Options){ this->m_TicksToWork = Options->PredeviceTicks; }// Тип классаEmulatorType GetType() { return EmulatorType_Predevice; }};// Эмулятор работы процесса после работы с устройствомclass PostdeviceEmulator : public BaseNodeviceEmulator {public:// Конструктор классаPostdeviceEmulator(ProcessOptions* Options){ this->m_TicksToWork = Options->PostdeviceTicks; }// Тип классаEmulatorType GetType() { return EmulatorType_Postdevice; }};// Эмулятор работы процесса с устройствомclass IndeviceEmilator : public BaseEmulator {public:// Конструктор классаIndeviceEmilator(ProcessOptions* Options) {this->m_Options = Options;this->m_DeviceStep = (Options->DeviceCount&& (Options->IndeviceTicks || Options->WaitDeviceTicks)) ? -1 : 0;this->m_SleepToTick = 0;this->m_TicksToWork = Options->IndeviceTicks;}protected:ProcessOptions* m_Options; // Ссылка на шаблон работы процессаint m_DeviceStep;// Текущий шаг в устройствеint m_SleepToTick;// Ожидание до указанного здесь времениint m_TicksToWork;// Время, которое осталось обрабатывать устройствоResult m_LastResult; // Последний результат эмулятораpublic:// Отработать текущий шагResult DoTick(int TotalTick) {if (m_DeviceStep == -1) {if (!g_Devices->GetDevice()) return m_LastResult = Result_Wait;m_DeviceStep = m_Options->DeviceCount;}while (m_DeviceStep) {if (m_SleepToTick) { // Режим ожидания устройстваif (m_SleepToTick <= TotalTick) { // Ожидание оконченоm_SleepToTick = 0;m_TicksToWork = m_Options->IndeviceTicks;m_DeviceStep--;continue;} else return m_LastResult = Result_Wait; // Нужно ждать дальше} else { // Режим работыbool l_Runned = false;if (m_TicksToWork) { // Если работа не оконченаif (--m_TicksToWork) return m_LastResult = Result_Run;l_Runned = true; // Если работа выполнена на текущем шаге,// то следует вычислить такт окончания ожидания}– 13 –m_SleepToTick = TotalTick + m_Options->WaitDeviceTicks;if (l_Runned) {m_SleepToTick++; return m_LastResult = Result_Run; }else continue;}}g_Devices->ReleaseDevice();return m_LastResult = Result_Finish;};}// Эмулятор закончил эмуляцию своей части шаблона работы процесса?bool IsFinished() { return !m_DeviceStep; }// Процесс находится в ожидании устройства (освобождения или ответа)?bool IsWaitOrSleep() { return m_LastResult == Result_Wait; }// Тип классаEmulatorType GetType() { return EmulatorType_Indevice; }// Вывод текущего состояния работы процессаvoid PrintState() { printf(m_DeviceStep == -1? " wait " : m_LastResult == Result_Run ? "d:run " : "d:slp "); }/*********************************************************************************************ProcessOptions*********************************************************************************************/ProcessOptions::ProcessOptions(int PredeviceTicks, int IndeviceTicks,int WaitDeviceTicks, int DeviceCount, int PostdeviceTicks,int TotalCount, int Priority) {this->PredeviceTicks = PredeviceTicks;this->IndeviceTicks= IndeviceTicks;this->WaitDeviceTicks = WaitDeviceTicks;this->DeviceCount= DeviceCount;this->PostdeviceTicks = PostdeviceTicks;this->TotalCount= TotalCount;this->Priority= Priority;}/*********************************************************************************************Process*********************************************************************************************/// Конструктор классаProcess::Process(ProcessOptions* Options) {this->m_Options = Options;m_CurrentPriority = Options->Priority;this->TotalStep = Options->TotalCount;this->m_Emulator = this->TotalStep ? new PredeviceEmulator(Options) : 0;this->m_FinishTick = 0;this->m_NoPrint = false;}// Отработать текущий шагResult Process::DoTick(int TotalTick) {bool l_Sleep = false;if (!m_Emulator) return m_LastResult = Result_Finish;if ((m_Emulator->GetType() == EmulatorType_Indevice&& ((IndeviceEmilator*)m_Emulator)->IsWaitOrSleep())|| !--m_CurrentPriority) m_CurrentPriority = m_Options->Priority;else l_Sleep = true;Result result;do {while (m_Emulator && m_Emulator->IsFinished())– 14 –}switch (m_Emulator->GetType()) {case EmulatorType_Predevice:delete m_Emulator;m_Emulator = new IndeviceEmilator(m_Options);break;case EmulatorType_Indevice:delete m_Emulator;m_Emulator = new PostdeviceEmulator(m_Options);break;case EmulatorType_Postdevice:delete m_Emulator;if (!--TotalStep) {m_Emulator = 0; m_FinishTick = TotalTick;return m_LastResult = Result_Finish; }m_Emulator = new PredeviceEmulator(m_Options);break;}if (l_Sleep) return m_LastResult = Result_Sleep;result = m_Emulator->DoTick(TotalTick);} while (result == Result_Finish);return m_LastResult = result;// Вывести состояние в последнем вызовеvoid Process::PrintState() {if (!m_Emulator) printf(m_NoPrint || !(m_NoPrint = true)? "" : " end ");else if (m_Options->Priority == m_CurrentPriority) m_Emulator->PrintState();else printf("sleep ");}// Вывести приоритет в последнем вызовеvoid Process::PrintPriority() {if (!m_Emulator) printf(m_NoPrint ? "" : " --- ");else if (m_Emulator && m_Emulator->GetType() == EmulatorType_Indevice&& ((IndeviceEmilator*)m_Emulator)->IsWaitOrSleep())printf(" ");else if (m_Options->Priority == m_CurrentPriority) printf(" 1>0 ");else {char buffer[7];strcpy(buffer, " ");itoa(m_CurrentPriority + 1, buffer + 1, 36);strcpy(buffer + 2, ">");itoa(m_CurrentPriority, buffer + 3, 36);strcpy(buffer + 4, " ");printf(buffer);}}// Вывести кол-во свободных устройствvoid Process::PrintSemafore() {char buffer[5];itoa(g_Devices->CurrentCount, buffer + 1, 36);buffer[0] = '-';strcpy(buffer + 2, "- ");printf(buffer);}// Время, на котором работа была оконченаint Process::GetFinishTick() { return m_FinishTick; }// Приоритет процесса по шаблонуint Process::GetPriority() { return m_Options->Priority; }// Последний результат работы процессаResult Process::GetResult() { return m_LastResult; }– 15 –Исходный код файла «Manager.h»:#pragma once// Класс эмулирует менеджер управления процессамиclass Manager {private:int m_Step;// Номер шага обработки всех процессовint m_TotalTick;// Текущее виртуальное время эмулятораint m_Idle;// Время простоя эмулируемого процессораint m_StepTicks;// Время работы на текущем шагеint m_StepIdle;// Время простоя на текущем шагеint m_ProcessCount;// Кол-во эмулируемых процессовProcess** m_Processes; // Ссылка на массив эмулируемых процессов// Форматирует текст о времени работы по числовым значениямvoid FormatTicks(char* Buffer, int Ticks, int Idle);// Выводит текст в центре области указанной длиныvoid PrintIntAtCenter(int Value, int Length);public:Manager(Process** Processes, int Count); // Конструктор классаbool RunStep();// Запустить обработку очередного шагаvoid PrintHeader(); // Вывод заголовка статистикиvoid PrintStep();// Вывод статистики по текущему шагуvoid PrintFooter(); // Вывод итогов статистики};Исходный код файла «Manager.cpp»:#include "stdafx.h"#include "Data.h"#include "Manager.h"// Конструктор классаManager::Manager(Process** Processes, int Count) {m_Step = 0;m_TotalTick = 0;m_Idle = 0;m_StepTicks = 0;m_StepIdle = 0;m_Processes = Processes;m_ProcessCount = Count;}// Запустить обработку очередного шагаbool Manager::RunStep() {int l_BeginTick = m_TotalTick;bool l_AllWait = true;bool l_AllFinish = true;for (int index = 0, count = m_ProcessCount; index < count; index++) {Process* l_Process = m_Processes[index];Result l_Result = l_Process->DoTick(m_TotalTick);if (l_Result == Result_Run) m_TotalTick++;if (l_Result != Result_Finish) {l_AllFinish = false;if (l_Result != Result_Wait) l_AllWait = false;}}– 16 –}m_Step++;m_StepIdle = 0;if ((m_StepTicks = m_TotalTick - l_BeginTick) == 0) {if (l_AllFinish) return false;if (l_AllWait) {m_TotalTick++;m_Idle++;m_StepIdle = 1;}}return true;// Вывод заголовка статистикиvoid Manager::PrintHeader() {char l_Buffer[32];int count = m_ProcessCount;printf("processes:");strcpy(l_Buffer, " x");for (int index = 0; index < count; index++) {l_Buffer[2] = index + 'A';printf(l_Buffer);}printf("sem.time/i\npriority: ");}strcpy(&l_Buffer[0], " high ");strcpy(&l_Buffer[8], " norm ");strcpy(&l_Buffer[16], " low ");strcpy(&l_Buffer[24], " (x) ");for (int index = 0; index < count; index++) {int l_Priority;switch (l_Priority = m_Processes[index]->GetPriority()) {case 1: printf(&l_Buffer[0]); break;case 2: printf(&l_Buffer[8]); break;case 3: printf(&l_Buffer[16]); break;default: l_Buffer[26] = l_Priority + '0'; printf(&l_Buffer[24]);break;}}printf("\n");// Вывод статистики по текущему шагуvoid Manager::PrintStep() {printf("\n");char buffer[11];itoa(m_Step, buffer, 10);int lenght = strlen(buffer);memcpy(buffer + 8 - lenght, buffer, lenght);memcpy(buffer, "step", 8 - lenght);strcpy(buffer + 8, ": ");printf(buffer);int count = m_ProcessCount;for (int index = 0; index < count; index++)m_Processes[index]->PrintPriority();– 17 –Process::PrintSemafore();FormatTicks(buffer, m_StepTicks, m_StepIdle);buffer[0] = '+';printf(buffer);printf("\n");for (int index = 0; index < count; index++)m_Processes[index]->PrintState();}FormatTicks(buffer, m_TotalTick - m_Idle, m_Idle);printf("=%s\n", buffer);// Форматирует текст о времени работы по числовым значениямvoid Manager::FormatTicks(char* Buffer, int Ticks, int Idle) {itoa(Ticks, Buffer, 10);int lenght = strlen(Buffer);if (lenght < 3) {memcpy(Buffer + 3 - lenght, Buffer, lenght);memcpy(Buffer, " ", 3 - lenght);}Buffer[3] = '/';itoa(Idle, Buffer + 4, 10);if (Buffer[5]) Buffer[6] = 0; else strcpy(Buffer + 5, " ");}// Вывод итогов статистикиvoid Manager::PrintFooter() {printf("----------");for (int index = m_ProcessCount; index; index--)printf("------");printf("----------\n");}printf("TotalTime:");for (int index = 0, count = m_ProcessCount; index < count; index++)PrintIntAtCenter(m_Processes[index]->GetFinishTick(), 6);printf("=");PrintIntAtCenter(m_TotalTick, 6);printf("\n");// Выводит текст в центре области указанной длиныvoid Manager::PrintIntAtCenter(int Value, int Length) {char* buffer = new char[Length + 1];itoa(Value, buffer, 10);int length = strlen(buffer);int begin = (Length - length) / 2;if (begin) {memcpy(buffer + begin, buffer, length);memset(buffer, ' ', begin);}memset(buffer + begin + length, ' ', Length - begin - length);buffer[Length] = 0;printf(buffer);}– 18 –Исходный код файла «Semaphore.cpp»:#include "stdafx.h"#include "Data.h"#include "Manager.h"#define ProcessesCount 7// Инициализация менеджера процессов, задание параметров эмуляцииManager* Initialize() {// Задание шаблонов работы процессовProcessOptions* l_OptionsH = new ProcessOptions(2, 1, 2, 3, 1, 2, 1);ProcessOptions* l_OptionsN = new ProcessOptions(2, 1, 2, 3, 1, 2, 2);ProcessOptions* l_OptionsL = new ProcessOptions(2, 1, 2, 3, 1, 2, 3);}Process** l_Processes = new Process*[ProcessesCount];l_Processes[0] = new Process(l_OptionsH);l_Processes[1] = new Process(l_OptionsH);l_Processes[2] = new Process(l_OptionsN);l_Processes[3] = new Process(l_OptionsN);l_Processes[4] = new Process(l_OptionsN);l_Processes[5] = new Process(l_OptionsL);l_Processes[6] = new Process(l_OptionsL);return new Manager(l_Processes, ProcessesCount);// Главная функция эмулятораint _tmain(int argc, _TCHAR* argv[]) {Manager* l_Manager = Initialize();l_Manager->PrintHeader();}bool result;do {result = l_Manager->RunStep();l_Manager->PrintStep();} while (result);l_Manager->PrintFooter();delete l_Manager;scanf("\n");return 0;– 19 –Результат работы программыЭмуляция производилась с тремя устройствами и семьюпроцессами.