
- •На курсовий проект (роботу) студента
- •К алендарний план
- •1 Постановка задачи
- •2 Выбор архитектуры вычислительной системы
- •3 Проектирование командного языка ос
- •4 Определение состава и общей структуры системы
- •5 Формирование базы данных ос
- •6 Программная реализация
- •7 Определение состава и общей структуры ос
7 Определение состава и общей структуры ос
Основное назначение мультипрограммной ОС - обеспечить исполнение множества процессов, совместно использующих ресурсы компьютера. Поэтому ключом к пониманию функционирования ОС является диаграмма состояний процесса.
Ядро ОС обеспечивает создание мультипроцессной среды и исполнение системных вызовов (примитивов) управления процессами, оперативной памятью и устройствами. Общая схема работы ядра раскрывает порядок выполнения основных системных вызовов и обработки прерываний. Так как язык системных вызовов реализуется, как правило, посредством механизма программных прерываний, ядро ОС является, по-существу, совокупностью обработчиков прерываний.
7.1 Структура системы
Операционная система взаимодействует с аппаратурой непосредственно, обеспечивая обслуживание программ и их независимость от деталей аппаратной конфигурации. Если представить систему состоящей из пластов, в ней можно выделить системное ядро, изолированное от пользовательских программ. Поскольку прикладные программы не зависят от аппаратного устройства исполняющей их машины, то они могут быть перенесены из одной системы в другую (учитывая, что в этих программах не предусмотрена работа с некоторым точно определенным оборудованием).
Программы, подобные командному процессору, взаимодействуют с ядром при помощи хорошо определенного набора обращений к операционной системе. Обращения к операционной системе понуждают ядро к выполнению различных операций, которых требует вызывающая программа, и обеспечивают обмен данными между ядром и программой. Другие прикладные программы располагаются выше указанных программ, на верхнем уровне.
Самый общий взляд на архитектуру UNIX позволяет увидеть двухуровневую модель системы, состоящую из пользовательской и системной части – ядра(рисунок 7.1). Ядро непосредственно взаимодействует с аппаратной частью компьютера, изолируя прикладные программы (процессы в пользовательской части операционной системы) от особенностей ее архитектуры. Ядро имеет набор услуг, предоставляемых прикладным программам посредством системных вызовов. Таким образом, в системе можно выделить два уровня привилегий: уровень системы (привилегии специального пользователя root).
Рисунок 7.1 Архитектура операционной системы
Важную часть системных программ составляют демоны. Демон — это процесс, выполняющий опеределенную функцию в системе, который запускается при старте системы и не связан ни с одним пользовательским терминалом. Демоны предоставляют пользователям определенные сервисы, примерами которых могут служить системный журнал, веб-сервер и т. п.
7.2 Первоначальная загрузка
Для того, чтобы перевести систему из неактивное состояние в активное, администратор выполняет процедуру "начальной загрузки". На разных машинах эта процедура имеет свои особенности, однако во всех случаях она реализует одну и ту же цель: загрузить копию операционной системы в основную память машины и запустить ее на исполнение.
В системе UNIX процедура начальной загрузки заканчивается считыванием с диска в память блока начальной загрузки (нулевого блока). Программа, содержащаяся в этом блоке, загружает из файловой системы ядро ОС. После загрузки ядра системы в память, ядро запускается на выполнение.
7.3 Файловая система ОС
Рассмотрим ключевые особенности данной системы. Итак, файлы характеризуются:
Иерархической структурой;
согласованной обработкой массивов данных;
возможностью создания и удаления файлов;
защитой информации в файлах и т.д.
Файловая система представляет собой дерево, с единственной основой – корнем (root), обозначающимся как, а воглаве этого главного корня стоит главный супер администратор с логином "root" по умолчанию. Каждая вершина в древовидной структуре файловой системы, кроме листьев, является каталогом файлов, а файлы, соответствующие дочерним вершинам, являются либо каталогами, либо обычными файлами, либо файлами устройств.
Каталоги похожи на обычные файлы в том смысле, что система представляет информацию в каталоге набором байтов, но эта информация включает в себя имена файлов в каталоге в объявленном формате.
7.4 Устройства
Для пользователя система UNIX трактует устройства так, как если бы они были файлами. Устройства, для которых назначены специальные файлы устройств, становятся вершинами в структуре файловой системы. Обращение программ к устройствам имеет тот же самый синтаксис, что и обращение к обычным файлам; семантика операций чтения и записи по отношению к устройствам в большой степени совпадает с семантикой операций чтения и записи обычных файлов. Способ защиты устройств совпадает со способом защиты обычных файлов.
7.5 Процессы
Программой называется исполняемый файл, а процессом называется последовательность операций программы или часть программы при ее выполнении. В системе UNIX может одновременно выполняться множество процессов (эту особенность иногда называют мультипрограммированием или многозадачным режимом), при чем их число логически не ограничивается, и множество частей программы (такой как copy) может одновременно находиться в системе. Различные системные операции позволяют процессам порождать новые процессы, завершают процессы, синхронизируют выполнение этапов процесса и управляют реакцией на наступление различных событий. Благодаря различным обращениям к операционной системе, процессы выполняются независимо друг от друга.
Возможный набор состояний процесса содержится в следующем перечне:
Процесс выполняется в режиме задачи.
Процесс выполняется в режиме ядра.
Процесс не выполняется, но готов к запуску под управлением ядра.
Процесс приостановлен и находится в оперативной памяти.
Процесс готов к запуску, но программа подкачки (нулевой процесс) должна еще загрузить процесс в оперативную память, прежде чем он будет запущен под управлением ядра.
Процесс приостановлен и программа подкачки выгрузила его во внешнюю память, чтобы в оперативной памяти освободить место для других процессов.
Процесс возвращен из привилегированного режима (режима ядра) в непривилегированный (режим задачи), ядро резервирует его и переключает контекст на другой процесс.
Процесс вновь создан и находится в переходном состоянии; процесс существует, но не готов к выполнению, хотя и не приостановлен. Это состояние является начальным состоянием всех процессов, кроме нулевого.
Процесс вызывает системную функцию exit и прекращает существование. Однако, после него осталась запись, содержащая код выхода, и некоторая хронометрическая статистика, собираемая родительским процессом. Это состояние является последним состоянием процесса.
Диспетчеризация процессов в системе UNIX
Рисунок 7.2 представляет собой полную диаграмму переходов процесса из состояния в состояние. Рассмотрим с помощью модели переходов типичное поведение процесса.
Ситуации, которые будут обсуждаться, несколько искусственны и процессы не всегда имеют дело с ними, но эти ситуации вполне применимы для иллюстрации различных переходов.Начальным состоянием модели является создание процесса родительским процессом с помощью системной функции fork; из этого состояния процесс неминуемо переходит в состояние готовности к запуску (3 или 5). Для простоты предположим, что процесс перешел в состояние «готовности к запуску в памяти» (3). Планировщик процессов в конечном счете выберет процесс для выполнения и процесс перейдет в состояние «выполнения в режиме ядра», где доиграет до конца роль, отведенную ему функцией fork.
Рисунок 7.2 – Диаграмма переходов процесса из состояния в состояние
После всего этого процесс может перейти в состояние «выполнения в режиме задачи». По прохождении определенного периода времени может произойти прерывание работыпроцессора по таймеру и процесс снова перейдет в состояние «выполнения в режиме ядра».Как только программа обработки прерывания закончит работу, ядру может понадобитьсяподготовить к запуску другой процесс, поэтому первый процесс перейдет в состояние «резервирования», уступив дорогу второму процессу. Состояние «резервирования» в действительности не отличается от состояния «готовности к запуску в памяти» (пунктирная линия на рисунке, соединяющая между собой оба состояния, подчеркивает их эквивалентность), но они выделяются в отдельные состояния, чтобы подчеркнуть, что процесс, выполняющийся в режиме ядра, может быть зарезервирован только в том случае, если он собирается вернуться в режим задачи. Следовательно, ядро может при необходимости подкачивать процесс из состояния «резервирования». При известных условиях планировщик выберет процесс для исполнения и тот снова вернется в состояние «выполнения в режиме задачи».
Когда процесс выполняет вызов системной функции, он из состояния «выполнения в режиме задачи» переходит в состояние «выполнения в режиме ядра». Предположим, что системной функции требуется ввод-вывод с диска и поэтому процесс вынужден дожидаться завершения ввода-вывода. Он переходит в состояние «приостанова в памяти», в котором будет находиться до тех пор, пока не получит извещения об окончании ввода-вывода. Когда ввод-вывод завершится, произойдет аппаратное прерывание работы центрального процессора и программа обработки прерывания возобновит выполнение процесса, в результате чего он перейдет в состояние «готовности к запуску в памяти».
Предположим, что система выполняет множество процессов, которые одновременно никак не могут поместиться в оперативной памяти, и программа подкачки (нулевой процесс) выгружает один процесс, чтобы освободить место для другого процесса, находящегося в состоянии «готов к запуску, но выгружен». Первый процесс, выгруженный из оперативной памяти, переходит в то же состояние. Когда программа подкачки выбирает наиболее подходящий процесс для загрузки в оперативную память, этот процесс переходит в состояние «готовности к запуску в памяти». Планировщик выбирает процесс для исполнения и он переходит в состояние «выполнения в режиме ядра». Когда процесс завершается, он исполняет системную функцию exit, последовательно переходя в состояния «выполнения в режиме ядра» и, наконец, в состояние «прекращения существования».
Процесс может управлять некоторыми из переходов на уровне задачи. Во-первых, один процесс может создать другой процесс. Тем не менее, в какое из состояний процесс перейдет после создания (т. е. в состояние «готов к выполнению, находясь в памяти» или в состояние «готов к выполнению, но выгружен») зависит уже от ядра. Процессу эти состояния н подконтрольны. Во-вторых, процесс может обратиться к различным системным функциям чтобы перейти из состояния «выполнения в режиме задачи» в состояние «выполнения режиме ядра», а также перейти в режим ядра по своей собственной воле. Тем не менее момент возвращения из режима ядра от процесса уже не зависит; в результате каких-тсобытий он может никогда не вернуться из этого режима и из него перейдет в состояние «прекращения существования». Наконец, процесс может завершиться с помощью функции exit по своей собственной воле, но как указывалось ранее, внешние события могут потребовать завершения процесса без явного обращения к функции exit. Все остальные переходы относятся к жестко закрепленной части модели, закодированной в ядре, и являются результатом определенных событий, реагируя на них в соответствии с правилами, сформулированными в этой и последующих главах. Некоторые из правил уже упоминались: например, то, что процесс может выгрузить другой процесс,выполняющийся в ядре.
Две принадлежащие ядру структуры данных описывают процесс: запись в таблице процессов и пространство процесса. Таблица процессов содержит поля, которые должны быть всегда доступны ядру, а пространство процесса — поля, необходимость в которы возникает только у выполняющегося процесса. Поэтому ядро выделяет место для пространства процесса только при создании процесса: в нем нет необходимости, если записи в таблице процессов не соответствует конкретный процесс.
Запись в таблице процессов состоит из следующих полей:
• Поле состояния, которое идентифицирует состояние процесса.
• Поля, используемые ядром при размещении процесса и его пространства в основной или внешней памяти. Ядро использует информацию этих полей для переключения контекстана процесс, когда процесс переходит из состояния «готов к выполнению, находясь в памяти в состояние «выполнения в режиме ядра» или из состояния «резервирования» в состояние «выполнения в режиме задачи». Кроме того, ядро использует эту информацию при перекачки процессов из и в оперативную память (между двумя состояниями «в памяти» и двумя состояниями «выгружен»). Запись в таблице процессов содержит также поле, описывающее размер процесса и позволяющее ядру планировать выделение пространства для процесса.
Несколько пользовательских идентификаторов (UID), устанавливающих различные привилегии процесса. Поля UID, например, описывают совокупность процессов, могущих обмениваться сигналами.
Идентификаторы процесса (PID), указывающие взаимосвязь между процессами. Значения полей PID задаются при переходе процесса в состояние «создан» во время выполнения функции fork.
Дескриптор события (устанавливается тогда, когда процесс приостановлен). В данной главе будет рассмотрено использование дескриптора события в алгоритмах функций sleep и wakeup.
Параметры планирования, позволяющие ядру устанавливать порядок переход процессов из состояния «выполнения в режиме ядра» в состояние «выполнения в режиме задачи».
Поле сигналов, в котором перечисляются сигналы, посланные процессу, но еще н обработанные.
Различные таймеры, описывающие время выполнения процесса и использование ресурсов ядра и позволяющие осуществлять слежение за выполнением и вычислять приоритет планирования процесса. Одно из полей является таймером, который устанавливает пользователь и который необходим для посылки процессу сигнала тревоги. Пространство процесса содержит поля, дополнительно характеризующие состояния процесса.
В системе разделения времени ядро предоставляет процессу ресурсы центрального процессора (ЦП) на интервал времени, называемый квантом, по истечении которого выгружает этот процесс и запускает другой, периодически переупорядочивая очередь процессов. Алгоритм планирования процессов в системе UNIX использует время выполнения в качестве параметра. Каждый активный процесс имеет приоритет планирования; ядро переключает контекст на процесс с наивысшим приоритетом. При переходе выполняющегося процесса из режима ядра в режим задачи ядро пересчитывает его приоритет, периодически и в режиме задачи переустанавливая приоритет каждого процесса, готового к выполнению.
То есть, в соответствии с этим принципом ядро предоставляет процессу ресурсы ЦП на квант времени, по истечении которого выгружает этот процесс и возвращает его в одну из нескольких очередей, регулируемых приоритетами. Прежде чем процесс завершится, ему может потребоваться множество раз пройти через цикл с обратной связью. Когда ядро выполняет переключение контекста и восстанавливает контекст процесса, процесс возобновляет выполнение с точки приостановки.
В основе многих вытесняющих алгоритмов планирования лежит концепция квантования. В соответствии с этой концепцией каждому потоку поочередно для выполнения предоставляется ограниченный непрерывный период процессорного времени — квант. Смена активного потока происходит, если:
поток завершился и покинул систему;
произошла ошибка;
поток перешел в состояние ожидания;
исчерпан квант процессорного времени, отведенный данному потоку.
Поток, который исчерпал свой квант, переводится в состояние готовности и ожидает, когда ему будет предоставлен новый квант процессорного времени, а на выполнение в соответствии с определенным правилом выбирается новый поток из очереди готовых. Граф состояний потока, изображенный на рис. 7.3, соответствует алгоритму планирования, основанному на квантовании.
Рисунок 7.3 – Граф состояний потока в системе с квантованием
Чем больше потоков в системе, тем больше время ожидания, тем меньше возможности вести одновременную интерактивную работу нескольким пользователям. Но если величина кванта выбрана очень небольшой, то значение произведения q(n-l) все равно будет достаточно мало для того, чтобы пользователь не ощущал дискомфорта от присутствия в системе других пользователей. Типичное значение кванта в системах разделения времени составляет десятки миллисекунд.
7.6 Общий алгоритм диспетчеризации
Сразу после переключения контекста ядро запускает алгоритм планирования выполнения процессов, выбирая на выполнение процесс с наивысшим приоритетом среди процессов, находящихся в состояниях "резервирования" и "готовности к выполнению, будучи загруженным в память". Рассматривать процессы, не загруженные в память, не имеет смысла, поскольку не будучи загружен, процесс не может выполняться. Если наивысший приоритет имеют сразу несколько процессов, ядро, используя принцип кольцевого списка (карусели), выбирает среди них тот процесс, который находится в состоянии "готовности к выполнению" дольше остальных. Если ни один из процессов не может быть выбран для выполнения, ЦП простаивает до момента получения следующего прерывания, которое произойдет не позже чем через один таймерный тик; после обработки этого прерывания ядро снова запустит алгоритм планирования.
7.7 Архитектура ядра UNIX
Ядро системы рассматривается как некоторая модель. Файловая подсистема и подсистема управления процессами, два главных компонента ядра. Файловая подсистема управляет файлами, размещает записи файлов, управляет свободным пространством, доступом к файлам и поиском данных для пользователей. Процессы взаимодействуют с подсистемой управления файлами, используя при этом совокупность специальных обращений к операционной системе, таких как open (для того, чтобы открыть файл на чтение или запись), close, read, write, stat (запросить атрибуты файла), chown (изменить запись с информацией о владельце файла) и chmod (изменить права доступа к файлу).
Подсистема управления файлами обращается к данным, которые хранятся в файле, используя буферный механизм, управляющий потоком данных между ядром и устройствами внешней памяти. Буферный механизм, взаимодействуя с драйверами устройств ввода-вывода блоками, инициирует передачу данных к ядру и обратно.
Большинство информационных структур ядра размещается в таблицах фиксированного размера, а не в динамически выделенной памяти. Простота алгоритмов ядра представляется более важной, чем сжатие последних байтов оперативной памяти. Обычно в алгоритмах для поиска свободных мест в таблицах используются несложные циклы и этот метод более понятен и иногда более эффективен по сравнению с более сложными схемами выделения памяти.
Общая схема работы ядра ОС приведена на рисунке 7.4.
Рисунок 7.4 — Общая схема работы ядра
7.8 Прерывания и особые ситуации:
Система UNIX позволяет таким устройствам, как внешние устройства ввода-вывода и системные часы, асинхронно прерывать работу центрального процессора. По получении сигнала прерывания ядро операционной системы сохраняет свой текущий контекст (застывший образ выполняемого процесса), устанавливает причину прерывания и обрабатывает прерывание.
После того, как прерывание будет обработано ядром, прерванный контекст восстановится и работа продолжится так, как будто ничего не случилось. Устройствам обычно приписываются приоритеты в соответствии с очередностью обработки прерываний.
В процессе обработки прерываний ядро учитывает их приоритеты и блокирует обслуживание прерывания с низким приоритетом на время обработки прерывания с более высоким приоритетом.
Особые ситуации связаны с возникновением незапланированных событий, вызванных процессом, таких как недопустимая адресация, задание привилегированных команд, деление на ноль и т.д.
Различают некоторое количество уровней прерывания. Их можно перечислить как (от высшего к низшему):
машинные сбои;
системные часы.
диск;
сетевое оборудование;
терминалы;
программное прерывание.
Установка уровня прерывания на определенное значение отсекает прерывания этого и более низких уровней, разрешая обработку только прерываний с более высоким приоритетом.
7.9 Функции операционной системы
Данные функции довольно очевидны. Среди них:
Управление выполнением процессов посредством их создания, завершения или приостановки и организации взаимодействия между ними.
Планирование очередности предоставления выполняющимся процессам времени центрального процессора (диспетчеризация). Процессы работают с центральным процессором в режиме разделения времени: центральный процессор выполняет процесс, по завершении отсчитываемого ядром кванта времени процесс приостанавливается и ядро активизирует выполнение другого процесса. Позднее ядро запускает приостановленный процесс.
Выделение выполняемому процессу оперативной памяти. Ядро операционной системы дает процессам возможность совместно использовать участки адресного пространства на определенных условиях, защищая при этом адресное пространство, выделенное процессу, от вмешательства извне. Если системе требуется свободная память, ядро освобождает память, временно выгружая процесс на внешние запоминающие устройства, которые называют устройствами выгрузки.
Выделение внешней памяти с целью обеспечения эффективного хранения информации и выборка данных пользователя. Именно в процессе реализации этой функции создается файловая система. Ядро выделяет внешнюю память под пользовательские файлы, мобилизует неиспользуемую память, структурирует файловую систему в форме, доступной для понимания, и защищает пользовательские файлы от несанкционированного доступа.
ВЫВОДЫ
В ходе выполнения курсового проекта были изучены теоретические сведенья об аппаратных платформах для ОС, особенностях алгоритмов управления ресурсами, организации оперативной памяти, средствах взаимодействия процессов, а также о методах организации файловой системы.
В результате выполнения данного курсового проекта была достигнута поставленная цель и спроектирована операционная система. Аппаратной платформой являются большие ЭВМ. Операционная система должна быть многозадачной, многопользовательской с многопроцессорной обработкой и вытесняющая многозадачностью. К особенностям областей использования относятся системы разделения времени и системы пакетной обработки. Организация оперативной памяти с переменными разделами и уплотнением памяти. Средствами взаимодействия процессов являются семафоры. Управление процессами происходит посредствам относительных приоритетов. Организация файловой системы UNIX.
Разработанный программный продукт моделирует работу файловой системы UNIX, а также многопоточную обработку данных с использованием семафоров в качестве средств взаимодействия процессов.
В дальнейшем данный программный продукт может быть улучшен и обновлен в соответствии с предъявляемыми к нему требованиями.
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ
Таненбаум Э. Современные операционные системы. 3-е изд. –СПб.: Питер, 2010. – 1120 с.: ил.
Харт, Джонсон, М. Системное программное обеспечение в среде Windows, 3-е издание. :Пер.с англ. М. Издательский дом «Вильямс», 2005. – 592 с.:ил.
Олифер Н. А., Олифер В. Г. Компьютерные сети. Принципы, технологии, протоколы: Учебник для вузов, 4-е изд. - СПб.: Питер, 2011. – 944 с.: ил.
Олифер Н. А., Олифер В. Г. Сетевые операционные системы- СПб.: Питер, 2007. – 864 с.: ил.
Вильямс А. Системное программирование в Windows 2000 для профессионалов – СПб: Питер, 2001. – 624 с.: ил.
Мешков А.,Тихонов Ю. Visual C++ и MFC. Программирование для Windows NT и Windows 95-:В трех томах. Том 1.-СПб.:BHV- Санкт-Петербург,1997.-464с.,ил.
Немнюгин С., Чаунин М., Кололкин А. Эффективная работа: UNIX. – СПб.: Питер,2001 -688 с.:ил.
Таненбаум Э. Компьютерные сети. 4-е изд. –СПб.: Питер, 2003. – 993с.: ил.
Морис Дж. Бах. Архитектура операционной системы Unix - Prentice-Hall, 1995. – 387c.
Робачевский А. Операционная система Unix. –СПб.: Питер, 2002. – 528с.: ил.
Приложение А
ТЕХНИЧЕСКОЕ ЗАДАНИЕ
А.1 Общие сведения
Название проекта: «Разработка операционной системы с заданными характеристиками».
Программный продукт проектируется студенткой 3-го курса Донецкого национального технического университета Института информатики и искусственного интеллекта, группы ПОС-09а Игнатова Филиппа Юрьевича.
Основанием для разработки данного проекта является задание, выданное кафедрой Программного обеспечения интеллектуальных систем (ПОИС).
Дата выдачи задания: 26.01.2012
Срок сдачи проекта: 27.04.2012
А.2 Назначение и цели создания проекта
Целью создания проекта является приобретение практических навыков создания операционных систем и комплексного инженерного проектирования программного обеспечения. Проект предназначен для демонстрации работы алгоритмов, связанных с операционными системами.
Проектируемая операционная система может быть использована в учебных заведениях в качестве наглядного пособия при обучении приемам и правилам построения интерактивной операционной системы.
А.3 Требования к КП
В курсовом проекте необходимо спроектировать компьютерную операционную систему c заданными характеристиками.
А.3.1 Требования к задачам КП
В КП должны быть реализованы следующие задачи:
реализация особенностей аппаратных платформ: большие ЭВМ;
реализация особенности алгоритмов управления ресурсами: многозадачные, многопользовательские, с многопроцессорной обработкой и вытесняющая многозадачностью;
реализация особенности областей использования: системы разделения времени и системы пакетной обработки;
организация оперативной памяти: с переменными разделами и уплотнением памяти;
выполнение средств взаимодействия процессов: семафоры(semaphores);
управление процессами: относительные приоритеты;
выполнение организации файловой системы: UNIX.
А.3.2 Требования к функциональности КП
Разрабатываемый в рамках данного проекта программный продукт должен удовлетворять следующим требованиям к его функциональности:
реализация особенностей аппаратных платформ: сети ЭВМ;
реализация особенности алгоритмов управления ресурсами: многозадачные, однопользовательские, с многопроцессорной обработкой;
реализация особенности областей использования: системы разделения времени и системы реального времени;
организация оперативной памяти: с использования внешней памяти, страничное распределение;
выполнение средств взаимодействия процессов: семафоры(semaphores);
управление процессами: квантование времени;
выполнение организации файловой системы: UNIX.
А.3.3 Требования к видам обеспечения
А.3.3.1 Требования к программному обеспечению
К программному обеспечению предъявляются следующие требования:
Программный продукт должен разрабатываться как операционная система.
При разработке проекта должна использоваться среда разработки Visual Studio.
А.3.3.2 Требования к техническому обеспечению
Требования к техническому обеспечению включают:
а) процессор с частотой 1,6 ГГц;
б) объем памяти RAM не менее 512 Мб;
в) свободное дисковое пространство около 128 Мб.
г) графический адаптер SVGA;
д) SVGA-монитор с разрешение 1280×1024;
е) манипулятор типа «мышь»;
ж) манипулятор типа «клавиатура».
А.3.3.3 Требования к организационному обеспечению
Организационным обеспечением по данному проекту составляет пояснительная записка. Она должна включать в себя следующие элементы:
Техническое задание на курсовой проект.
Руководство пользователя.
Экранные формы.
Листинг программы.
А.4 Порядок защиты проекта
При защите проекта должны соблюдаться следующие требования:
Защита проекта проводится в присутствии соответствующей приемной комиссии.
Для защиты проекта необходимо в оговоренные сроки представить:
задание на курсовой проект;
пояснительную записку на курсовой проект;
исполнимый файл программы.
А.5 Сроки выполнения курсового проекта
Стадии и этапы разработки КП представлены в таблице 5.1.
Таблица 5.1. Стадии и этапы разработки КП
№ |
Этапы работы |
Срок выполнения |
1 |
Постановка задания. Выбор темы курсового проекта. |
1-2 неделя |
2 |
Разработка ТЗ. |
3-4 неделя |
3 |
Анализ структуры программы |
5-6 неделя |
4 |
Создание алгоритмической и математической модели. |
7-8 неделя |
5 |
Разработка интерфейса и программирование сложной модели. |
9-10 неделя |
6 |
Отладка программы. |
11-12 неделя |
7 |
Оформление ПЗ. |
13 неделя |
8 |
Защита КП. |
14 неделя |
Приложение Б
РУКОВОДСТВО ПОЛЬЗОВАТЕЛЯ
Операционная система не имеет графической оболочки. Пользователю предоставляется командная строка для ввода различных пользовательских команд. Через неё пользователь может выполнять операции над файлами, хранящимися в файловой системе, запускать различные приложения, выполнять иные действия над ОС.
В начале работы приложения пользователь имеет возможность воспользоваться одним из 4 пунктов предоставляемого меню, вызов которого осуществляется посредством ввода номера соответствующего пункта меню. Первый пункт меню демонстрирует тестовую работу эмулятора файловой системы, и не требует от пользователя ввода какх-либо команд. Второй пункт позволяет пользователю самостоятельно задавать команды и их параметры. Третий пункт демонстрирует работу мнопоточных вычислений, результаты которых записываются в LOG-файл. Четвертый пункт предоставляет пользователь небольшую справку, содержащую список команд ФС и параметры, указываемые при вызове. На данный момент список следующий:
сreate <img_name, int size, int size_blocks> — создаёт файл-образ с именем img_name, размером size, параметр size_blocks — указывает на размер блоков данных файловой системы;
сopyfrom <img_name, file> — копирует в файл-образ с именем img_name файл с жесткого диска с именем file;
copyto <img_name, file, fileToHDD> — копирует из файла-образа (img_name) файл с именем file на жесткий диск. FileToHDD — задает имя итогового файла;
del <img_name, file> — удаляет с файла-образа (img_name) файл с именем file;
root- показывает информацию о файловой системе и выводит информацию о файлах содержащихся в ней;
format <img_name> — форматирует файл-образ (img_name);
mult - запустить многопоточные вычисления;
texit – выход.
Приложение В
ЭКРАННЫЕ ФОРМЫ
Рисунок В.1 – Главная форма
Рисунок В.2 – Результат выполнения теста
Рисунок В.3 – Результат выполнения команд над файловой системой
Рисунок В.4 –Результат многопоточных вычислений
Рисунок В.5 – Помощь
Приложение Г
Листинг программы
Файл «FileSystem.h»
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <vector>
#include <iostream>
using namespace std;
struct CInode
{
char *name_file;
int number;
int file_size;
int nBlocks[10];
int nCosBlocks[3];
};
struct CSuperBlock
{
int SizeINodes;
int SizeBlocks;
int size_FS;
};
class FileSystem
{
public:
FILE *img;
CSuperBlock SB;
vector<CInode> inodes;
public:
FileSystem();
~FileSystem();
bool Create(char *img_name, int size, int size_blocks);
bool CopyFromHDD(char *img_name, char *file);
bool CopyToHDD(char *img_name,char *file, char *fileToHDD);
bool Delete (char *img_name, char *file);
bool Format (char *img_name);
void ShowRoot();
};
Файл «FileSystem.сср»
#include "stdafx.h"
#include "FileSystem.h"
FileSystem::FileSystem() {}
FileSystem::~FileSystem() {}
bool FileSystem::Create(char *img_name, int size, int size_blocks)
{
SB.SizeBlocks = size_blocks;
SB.SizeINodes = sizeof(CInode);
SB.size_FS = size;
img = fopen(img_name,"w");
if(img == NULL)
return false;
for (int i=0;i<size;i++)
fputc('\0',img);
fclose(img);
return true;
}
bool FileSystem::CopyFromHDD(char *img_name, char *file)
{
FILE *fileHDD;
img = fopen(img_name,"r+");
fileHDD = fopen(file,"r+");
if(img == NULL || fileHDD == NULL)
return false;
char ch = fgetc(img);
int pos = 0;
while(ch!='\0') {
pos++;
fseek(img,pos*SB.SizeBlocks,SEEK_SET);
ch = fgetc(img); }
fseek(img,pos*SB.SizeBlocks,SEEK_SET);
int size_read = 0, j = 0, j_1 = 0;
CInode node;
CInode node_new1;node_new1.nBlocks[j] = node_new1.file_size = 0;
node_new1.number = inodes.size()+1;
CInode node_new2;node_new2.nBlocks[j] = node_new2.file_size = 0;
node_new2.number = inodes.size()+2;
CInode node_new3;node_new3.nBlocks[j] = node_new3.file_size = 0;
node_new3.number = inodes.size()+3;
for(int i = 0; i < 10; i++)
{
node.nBlocks[i] = -1;
node_new1.nBlocks[i] = -1;
node_new2.nBlocks[i] = -1;
node_new3.nBlocks[i] = -1;
}
for(int i = 0; i < 3; i++)
node.nCosBlocks[i] = -1;
node.number = inodes.size();
node.nBlocks[j] = pos;
node.name_file = file;
while((ch=fgetc(fileHDD))!=EOF)
{
size_read++;
fputc(ch,img);
if(size_read == SB.SizeBlocks)
{
size_read = 0;
pos++;
if(j<10)
j++;
if(j<10)
node.nBlocks[j] = pos;
else
{
if(j == 10)
{
if(j_1 == 0)
node.nCosBlocks[0] = node_new1.number;
if(j_1 < 10)
{
node_new1.nBlocks[j_1] = pos;
j_1++;
}
else
{
j_1 = 0;
j++;
}}
if(j == 11)
{
if(j_1 == 0)
node.nCosBlocks[1] = node_new2.number;
if(j_1 < 10)
{
node_new2.nBlocks[j_1] = pos;
j_1++;
}
else
{
j_1 = 0;
j++;
}}
if(j == 12)
{
if(j_1 == 0)
node.nCosBlocks[2] = node_new3.number;
if(j_1 < 10)
{
node_new3.nBlocks[j_1] = pos;
j_1++;
}
else
{
j_1 = 0;
j++;
}}}}}
fseek(img,0,SEEK_SET);
node.file_size = (pos-node.nBlocks[0])*SB.SizeBlocks + size_read;
inodes.push_back(node);
if(node_new1.nBlocks[0] != -1)
inodes.push_back(node_new1);
if(node_new2.nBlocks[0] != -1)
inodes.push_back(node_new2);
if(node_new3.nBlocks[0] != -1)
inodes.push_back(node_new3);
return true;
}
void FileSystem::ShowRoot()
{
if(inodes.empty() == false)
{
cout<<"\nИнформация о ФС."<<endl;
cout<<"Размер ФС : "<<SB.size_FS<<" бт"<<endl;
cout<<"Размер блока : "<<SB.SizeBlocks<<" бт"<<endl;
cout<<"Размер инд. дескр.: "<<SB.SizeINodes<<" бт"<<endl;
cout<<"Название файла\tРазмер\tиндексный дискриптор"<<endl;
int dirty = 0;
for(int i = 0; i< inodes.size();i++)
dirty += inodes[i].file_size;
cout<<"Свободное место : "<<SB.size_FS - dirty<<endl;
for(int i = 0; i < inodes.size(); i++)
if(inodes[i].file_size != 0)
{
cout<<inodes[i].name_file<<"\t\t";
cout<<inodes[i].file_size<<" бт"<<'\t';
cout<<inodes[i].number<<endl;
}
}
else
cout<<"Файловая система пуста"<<endl;
cout<<endl;
}
bool FileSystem::CopyToHDD(char *img_name,char *file, char *fileToHDD)
{
int index_start = -1;
for(int i = 0; i < inodes.size(); i++)
if(inodes[i].name_file == fileToHDD)
{
index_start = i;
break; }
if(index_start == -1)
return false;
FILE *fileHDD;
img = fopen(img_name,"r");
fileHDD = fopen(file,"w");
if(img == NULL || fileHDD == NULL)
return false;
char ch;
for(int i = 0; i < 10; i++)
{
if(inodes[index_start].nBlocks[i] != -1)
{
fseek(img,inodes[index_start].nBlocks[i] * SB.SizeBlocks,SEEK_SET);
for(int j = 0; j < SB.SizeBlocks; j++)
{
ch = fgetc(img);
if(ch != '\0')
fputc(ch,fileHDD);
}}}
for(int i = 0; i <3; i++)
{
if(inodes[index_start].nCosBlocks[i] != -1)
{
for(int k = 0; k < 10; k++)
if(inodes[inodes[index_start].nCosBlocks[i]].nBlocks[k]!= -1)
{
fseek(img,inodes[inodes[index_start].nCosBlocks[i]].nBlocks[k] * SB.SizeBlocks,SEEK_SET);
for(int j = 0; j < SB.SizeBlocks; j++)
{
ch = fgetc(img);
if(ch != '\0')
fputc(ch,fileHDD);
}}}}
fclose(img);
fclose(fileHDD);
return true;
}
bool FileSystem::Delete(char *img_name, char *file)
{
img = fopen(img_name,"r+");
if(img == NULL)
return false;
int index_start = -1;
for(int i = 0; i < inodes.size(); i++)
if(inodes[i].name_file == file)
{
index_start = i;
break;
}
if(index_start == -1)
return false;
for(int i = 0; i < 10; i++)
{
if(inodes[index_start].nBlocks[i] != -1)
{
fseek(img,inodes[index_start].nBlocks[i] * SB.SizeBlocks,SEEK_SET);
for(int j = 0; j < SB.SizeBlocks; j++)
fputc('\0',img);
}
}
for(int i = 0; i <3; i++)
{
if(inodes[index_start].nCosBlocks[i] != -1)
{
for(int k = 0; k < 10; k++)
if(inodes[inodes[index_start].nCosBlocks[i]].nBlocks[k]!= -1)
{
fseek(img,inodes[inodes[index_start].nCosBlocks[i]].nBlocks[k] * SB.SizeBlocks,SEEK_SET);
for(int j = 0; j < SB.SizeBlocks; j++) fputc('\0',img);}}}
for(int i = 2; i > -1; i--)
{
if(inodes[index_start].nCosBlocks[i] != -1)
if(inodes[inodes[index_start].nCosBlocks[i]].nBlocks[0]!= -1)
inodes.erase(inodes.begin()+inodes[index_start].nCosBlocks[i]-1);
}
inodes.erase(inodes.begin()+index_start);
fclose(img);
return true;
}
bool FileSystem::Format(char *img_name)
{
img = fopen(img_name,"w");
if(img == NULL)return false;
fseek(img,0,SEEK_SET);
for (int i=0;i<SB.size_FS;i++)
fputc('\0',img);
inodes.erase(inodes.begin(),inodes.end());
return true;
}
Файл «Unix.cpp»
#include "stdafx.h"
#include "FileSystem.h"
#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <math.h>
#include <conio.h>
#include <fstream>
using namespace std;
#define VAR 22
ofstream LOGFILE;
HANDLE hThread1,hThread2,hThread3,hThread4,hThread5,hThread6,hThread7,hThread8,hFinalThread;
HANDLE hQuit=NULL;
DWORD id1,id2,id3,id4,id5,id6,id7,id8,idfinal;
double res[9];
HANDLE hSema, hSem;
double IT(double arg)
{
double res=0,step=arg/50,left,right;
for (double i=-arg;i<arg;i+=step)
{
left=fabs(cos(i)*sin(i));
right=fabs(cos(i+step)*sin(i+step));
res+=(left+right)*step/2;
}
return res;
}
double SS(double arg)
{
double res=0;
for (int i=1;i<fabs(arg);i++) res+=fabs(sin((float)i));
return res;
}
DWORD WINAPI Thread1(LPVOID)
{
SYSTEMTIME tTime;
WaitForSingleObject(hSema,INFINITE);
GetLocalTime(&tTime);
LOGFILE <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Создан поток 1;" << endl;
cout<<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Создан поток 1;" << endl;
GetLocalTime(&tTime);
LOGFILE.flush();
ReleaseSemaphore(hSema,1,NULL);
res[0]=IT(VAR*1);
MessageBox(NULL,L"1 поток завершен!",L"Выполнение", MB_TOPMOST);
cout <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Поток 1 завершил свою работу с результатом = " << res[0] << endl;
WaitForSingleObject(hSem,INFINITE);
GetLocalTime(&tTime);
LOGFILE <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Поток 1 завершил свою работу с результатом = " << res[0] << endl;
LOGFILE.flush();
ReleaseSemaphore(hSem,1,NULL);
return 0;
}
DWORD WINAPI Thread2(LPVOID)
{
SYSTEMTIME tTime;
WaitForSingleObject(hSema,INFINITE);
GetLocalTime(&tTime);
LOGFILE <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Создан поток 2;" << endl;
cout <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Создан поток 2;" << endl;
LOGFILE.flush();
ReleaseSemaphore(hSema,1,NULL);
res[1]=IT(VAR*2);
MessageBox(NULL,L"2 поток завершен!",L"Выполнение", MB_OK);
cout <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Поток 2 завершил свою работу с результатом = " << res[1] << endl;
WaitForSingleObject(hSem,INFINITE);
GetLocalTime(&tTime);
LOGFILE <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Поток 2 завершил свою работу с результатом = " << res[1] << endl;
LOGFILE.flush();
ReleaseSemaphore(hSem,1,NULL);
return 0;
}
DWORD WINAPI Thread3(LPVOID)
{
SYSTEMTIME tTime;
WaitForSingleObject(hSema,INFINITE);
GetLocalTime(&tTime);
LOGFILE <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Создан поток 3;" << endl;
cout <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Создан поток 3;" << endl;
LOGFILE.flush();
ReleaseSemaphore(hSema,1,NULL);
res[2]=IT(VAR*3);
MessageBox(NULL,L"3 поток завершен!",L"Выполнение", MB_OK);
cout <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Поток 3 завершил свою работу с результатом = " << res[2] << endl;
WaitForSingleObject(hSem,INFINITE);
GetLocalTime(&tTime);
LOGFILE <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Поток 3 завершил свою работу с результатом = " << res[2] << endl;
LOGFILE.flush();
ReleaseSemaphore(hSem,1,NULL);
return 0;
}
DWORD WINAPI Thread4(LPVOID)
{
SYSTEMTIME tTime;
WaitForSingleObject(hThread3,INFINITE);
WaitForSingleObject(hSema,INFINITE);
GetLocalTime(&tTime);
LOGFILE <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Создан поток 4;" << endl;
cout <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Создан поток 4;" << endl;
LOGFILE.flush();
ReleaseSemaphore(hSema,1,NULL);;
res[3]=IT(res[2]*VAR*4);
MessageBox(NULL,L"4 поток завершен!",L"Выполнение", MB_TOPMOST);
cout <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Поток 4 завершил свою работу с результатом = " << res[3] << endl;
WaitForSingleObject(hSem,INFINITE);
GetLocalTime(&tTime);
LOGFILE <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Поток 4 завершил свою работу с результатом = " << res[3] << endl;
LOGFILE.flush();
ReleaseSemaphore(hSem,1,NULL);
return 0;
}
DWORD WINAPI Thread5(LPVOID)
{
SYSTEMTIME tTime;
WaitForSingleObject(hThread3,INFINITE);
WaitForSingleObject(hSema,INFINITE);
GetLocalTime(&tTime);
LOGFILE <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Создан поток 5;" << endl;
cout <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Создан поток 5;" << endl;
LOGFILE.flush();
ReleaseSemaphore(hSema,1,NULL);
res[4]=IT(res[2]*VAR*5);
MessageBox(NULL,L"5 поток завершен!",L"Выполнение", MB_TOPMOST);
cout <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Поток 5 завершил свою работу с результатом = " << res[4] << endl;
WaitForSingleObject(hSem,INFINITE);
GetLocalTime(&tTime);
LOGFILE <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Поток 5 завершил свою работу с результатом = " << res[4] << endl;
LOGFILE.flush();
ReleaseSemaphore(hSem,1,NULL);
return 0;
}
DWORD WINAPI Thread6(LPVOID)
{
SYSTEMTIME tTime;
WaitForSingleObject(hThread3,INFINITE);
WaitForSingleObject(hSema,INFINITE);
GetLocalTime(&tTime);
LOGFILE <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Создан поток 6;" << endl;
cout <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Создан поток 6;" << endl;
LOGFILE.flush();
ReleaseSemaphore(hSema,1,NULL);
res[5]=IT(res[2]*VAR*6);
MessageBox(NULL,L"6 поток завершен!",L"Выполнение", MB_OK);
cout <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Поток 6 завершил свою работу с результатом = " << res[5] << endl;
WaitForSingleObject(hSem,INFINITE);
GetLocalTime(&tTime);
LOGFILE <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Поток 6 завершил свою работу с результатом = " << res[5] << endl;
LOGFILE.flush();
ReleaseSemaphore(hSem,1,NULL);
return 0;
}
DWORD WINAPI Thread7(LPVOID)
{
SYSTEMTIME tTime;
WaitForSingleObject(hThread1,INFINITE);
WaitForSingleObject(hThread2,INFINITE);
WaitForSingleObject(hSema,INFINITE);
GetLocalTime(&tTime);
LOGFILE <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<<"Создан поток 7;" << endl;
cout <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<<"Создан поток 7;" << endl;
LOGFILE.flush();
ReleaseSemaphore(hSema,1,NULL);
res[6]=SS((res[0]+res[1])*VAR*7);
MessageBox(NULL,L"7 поток завершен!",L"Выполнение", MB_OK);
cout <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Поток 7 завершил свою работу с результатом = " << res[6] << endl;
WaitForSingleObject(hSem,INFINITE);
GetLocalTime(&tTime);
LOGFILE <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Поток 7 завершил свою работу с результатом = " << res[6] << endl;
LOGFILE.flush();
ReleaseSemaphore(hSem,1,NULL);
return 0;
}
DWORD WINAPI Thread8(LPVOID)
{
SYSTEMTIME tTime;
WaitForSingleObject(hThread4,INFINITE);
WaitForSingleObject(hThread5,INFINITE);
WaitForSingleObject(hSema,INFINITE);
GetLocalTime(&tTime);
LOGFILE <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Создан поток 8;" << endl;
cout <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Создан поток 8;" << endl;
LOGFILE.flush();
ReleaseSemaphore(hSema,1,NULL);
res[7]=SS((res[3]+res[4])*VAR*8);
MessageBox(NULL,L"8 поток завершен!",L"Выполнение", MB_OK);
cout <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Поток 8 завершил свою работу с результатом = " << res[7] << endl;
WaitForSingleObject(hSem,INFINITE);
GetLocalTime(&tTime);
LOGFILE <<tTime.wHour<<":"<<tTime.wMinute<<":"<<tTime.wSecond<<" "<< "Поток 8 завершил свою работу с результатом = " << res[7] << endl;
LOGFILE.flush();
ReleaseSemaphore(hSem,1,NULL);
return 0;
}
DWORD WINAPI FinalThread(LPVOID)
{ WaitForSingleObject(hThread6,INFINITE);
WaitForSingleObject(hThread7,INFINITE);
WaitForSingleObject(hThread8,INFINITE);
res[8]=res[5]+res[6]+res[7];
return 0;}
DWORD WINAPI Multi()
{
hQuit=CreateSemaphore(NULL,1,1,L"Semaphore");
if(hQuit == NULL) {
MessageBox(NULL, L"Ошибка при создании семафора", L"Warning",MB_ICONSTOP);
return FALSE; }
if (GetLastError()==ERROR_ALREADY_EXISTS)
{MessageBox(NULL,L"Программа уже используется!",L"Warning",MB_SETFOREGROUND);
return 1;}
LOGFILE.open(L"result.log");
hSema=CreateSemaphore(NULL,1,1,L"Sema");
if(hSema == NULL) {
MessageBox(NULL, L"Ошибка при создании семафора", L"Warning", MB_ICONSTOP);
return FALSE; }
hSem=CreateSemaphore(NULL,1,1,L"Sem");
if(hSem == NULL) {
MessageBox(NULL, L"Ошибка при создании семафора", L"Warning", MB_ICONSTOP);
return FALSE;}
hThread1 = CreateThread(0, 0, Thread1, 0, 0, &id1);
hThread2 = CreateThread(0, 0, Thread2, 0, 0, &id2);
hThread3 = CreateThread(0, 0, Thread3, 0, 0, &id3);
hThread4 = CreateThread(0, 0, Thread4, 0, 0, &id4);
hThread5 = CreateThread(0, 0, Thread5, 0, 0, &id5);
hThread6 = CreateThread(0, 0, Thread6, 0, 0, &id6);
hThread7 = CreateThread(0, 0, Thread7, 0, 0, &id7);
hThread8 = CreateThread(0, 0, Thread8, 0, 0, &id8);
hFinalThread = CreateThread(0, 0, FinalThread, 0, 0, &idfinal);
DWORD tquit = WaitForSingleObject(hFinalThread, 20000);
if (tquit==WAIT_TIMEOUT)
{ MessageBox(NULL,L"Время вышло! Работа прервана!",L"Warning", MB_TOPMOST);
LOGFILE << "Время вышло! Работа прервана!" << endl;
TerminateThread(hThread1,0);
TerminateThread(hThread2,0);
TerminateThread(hThread3,0);
TerminateThread(hThread4,0);
TerminateThread(hThread5,0);
TerminateThread(hThread6,0);
TerminateThread(hThread7,0);
TerminateThread(hThread8,0);
TerminateThread(hFinalThread,0);}
else
{
LOGFILE << "Результат работы программы = " << res[8]<< endl;
cout << "Результат работы программы = " << res[8]<< endl;
}
LOGFILE.flush();
CloseHandle(hQuit);
CloseHandle(hSema);
CloseHandle(hSem);
CloseHandle(hThread1);
CloseHandle(hThread2);
CloseHandle(hThread3);
CloseHandle(hThread4);
CloseHandle(hThread5);
CloseHandle(hThread6);
CloseHandle(hThread7);
CloseHandle(hThread8);
CloseHandle(hFinalThread);
LOGFILE.close();
MessageBox(NULL,L"Программа выполнена!",L"Готово!", MB_TOPMOST);
}
int main()
{
FileSystem FS;
setlocale (LC_ALL, ".1251");
printf("\tUnix-Emulator v.1.0\nCreated by Stulikova N. V.\n\n>");
char c = '1';
while (c != '4')
{
printf(" Реализация эмулятора ФС:\n\n");
printf("1. Тест\n");
printf("2. Работа с ФС\n");
printf("3. Многопоточные вычисления\n");
printf("4. Помощь\n");
printf("0. Выход\n\n");
printf(">> ");
c = _getch();
switch(c)
{
case '0':
exit(0);
case '1':
system ("CLS");
if(FS.Create("fs.img",4096,64) == true)
cout<<"Образ ФС создан! \n";
else cout<<"Не удалось создать образ ФС! \n";
if(FS.CopyFromHDD("fs.img","t1.txt") == true)
cout<<"Файл t1.txt скопирован с диска! \n";
else cout<<"Не удалось скопировать файл t1.txt с диска! \n";
if(FS.CopyFromHDD("fs.img","t2.txt") == true)
cout<<"Файл t2.txt скопирован с диска! \n";
else cout<<"Не удалось скопировать файл t2.txt с диска! \n";
if(FS.CopyFromHDD("fs.img","t3.txt") == true)
cout<<"Файл t3.txt скопирован с диска! \n";
else cout<<"Не удалось скопировать файл t3.txt с диска! \n";
if(FS.CopyFromHDD("fs.img","t4.txt") == true)
cout<<"Файл t4.txt скопирован с диска! \n";
else cout<<"Не удалось скопировать файл t4.txt с диска! \n";
FS.ShowRoot();
if(FS.Delete("fs.img","t2.txt") == true)
cout<<"Файл t2.txt удалён!"<<endl;
else cout<<"Не удалось удалить файл t2.txt! \n";
FS.ShowRoot();
if(FS.CopyToHDD("fs.img","t1_copy.txt","t1.txt") == true)
cout<<"Файл t1_copy.txt скопирован на диск успешно!"<<endl;
else cout<<"Не удалось скопировать файл t1.txt на диск! \n";
if(FS.CopyToHDD("fs.img","t2_copy.txt","t2.txt") == true)
cout<<"Файл t2_copy.txt скопирован на диск успешно!"<<endl;
else cout<<"Не удалось скопировать файл t2.txt на диск! \n";
if(FS.CopyToHDD("pish.img","t4_copy.txt","t4.txt") == true)
cout<<"Файл t4_copy.txt скопирован на диск успешно!"<<endl;
else cout<<"Не удалось скопировать файл t4.txt на диск! \n";
if(FS.Format("fs.img") == true)
cout<<"Форматирование произведено успешно!"<<endl<<endl;
else cout<<"Форматирование не удалось!"<<endl<<endl;
system ("PAUSE");
break;
case '2':
system ("CLS");
while (true)
{
cout<<">";
char command[10];
char nameFS[10];
char namefile[10];
int sizeFS, size;
char open[10]="open";
cin>>command;
if (strcmp(command,"exit") == 0 || strcmp(command,"quit") == 0)
{
return 0;
};
bool C=true;
if (strcmp(command,"create") == 0)
{
cin>>nameFS;
cin>>sizeFS;
cin>>size;
FS.Create(strcat(nameFS,".img"),sizeFS,size);
cout<<"Образ ФС создан! \n";
}
if (strcmp(command,"copyfrom") == 0)
{
cin>>nameFS;
cin>>namefile;
FS.CopyFromHDD(strcat(nameFS,".img"),strcat(namefile,".txt"));
cout<<"Файл "<<namefile<< "скопирован с диска! \n"<<endl;
}
if (strcmp(command,"copyto") == 0)
{
cin>>nameFS;
cin>>namefile;
FS.CopyToHDD(strcat(nameFS,".img"),strcat(strcat(namefile,"_copy"),".txt"),namefile);
cout<<"Файл "<<namefile<<" скопирован на диск успешно!"<<endl;
//FS.CopyToHDD(strcat(nameFS,".img"),"copy.txt",strcat(namefile,".txt"));
//FS.CopyToHDD("pish.img","t1_copy.txt","t1.txt");
}
if (strcmp(command,"del") == 0)
{
cin>>nameFS;
cin>>namefile;
FS.Delete(strcat(nameFS,".img"),strcat(namefile,".txt"));
cout<<"Файл "<<namefile<<" удалён!"<<endl;
}
if (strcmp(command,"format") == 0)
{
cin>>nameFS;
FS.Format(strcat(nameFS,".img"));
cout<<"Форматирование произведено успешно!"<<endl<<endl;
}
if (strcmp(command,"root") == 0)
{
FS.ShowRoot();
}
if (strcmp(command,"mult") == 0)
{
Multi();
}
if (strcmp(command,"help") == 0)
{
cout<<"\tсreate <img_name, int size, int size_blocks> — создаёт файл-образ с именем img_name, размером size, параметр size_blocks — указывает на размер блоков данных файловой системы.\n"<<endl;
cout<<"\tсopyfrom <img_name, file> — копирует в файл-образ с именем img_name файл с жесткого диска с именем file.\n"<<endl;
cout<<"\tcopyto <img_name, file, fileToHDD> — копирует из файла-образа (img_name) файл с именем file на жесткий диск. FileToHDD — задает имя итогового файла.\n"<<endl;
cout<<"\tdel <img_name, file> — удаляет с файла-образа (img_name) файл с именем file.\n"<<endl;
cout<<"\troot- показывает информацию о файловой системе и выводит информацию о файлах содержащихся в ней\n"<<endl;
cout<<"\tformat <img_name> — форматирует файл-образ (img_name)\n"<<endl;
cout<<"\tmult - запустить многопоточные вычисления\n"<<endl;
cout<<"\texit - выход\n";
cout<<endl;
};
}
system ("PAUSE");
break;
case '3':
Multi();
break;
case '4':
system ("CLS");
cout<<"\tсreate <img_name, int size, int size_blocks> — создаёт файл-образ с именем img_name, размером size, параметр size_blocks — указывает на размер блоков данных файловой системы.\n"<<endl;
cout<<"\tсopyfrom <img_name, file> — копирует в файл-образ с именем img_name файл с жесткого диска с именем file.\n"<<endl;
cout<<"\tcopyto <img_name, file, fileToHDD> — копирует из файла-образа (img_name) файл с именем file на жесткий диск. FileToHDD — задает имя итогового файла.\n"<<endl;
cout<<"\tdel <img_name, file> — удаляет с файла-образа (img_name) файл с именем file.\n"<<endl;
cout<<"\troot- показывает информацию о файловой системе и выводит информацию о файлах содержащихся в ней\n"<<endl;
cout<<"\tformat <img_name> — форматирует файл-образ (img_name)\n"<<endl;
cout<<"\tmult - запустить многопоточные вычисления\n"<<endl;
cout<<"\texit - выход\n";
cout<<endl;
system ("PAUSE");
break;
default:
printf("\n\nОшибка!");
printf("\nВводите только 1, 2, 3, 4 и 0!");
system ("PAUSE");
break;
}
}
system("pause");
return 0;}